メインコンテンツにスキップ
バージョン: 3.5.2

ルーティング

Docusaurus のルーティングシステムは、シングルページアプリケーションの慣例に従います。1 つのルートに対して 1 つのコンポーネントです。このセクションでは、まず 3 つのコンテンツプラグイン(ドキュメント、ブログ、ページ)内のルーティングについて説明し、次に、基盤となるルーティングシステムについて説明します。

コンテンツプラグインのルーティング

すべてのコンテンツプラグインは、`routeBasePath` オプションを提供します。これは、プラグインがルートを追加する場所を定義します。デフォルトでは、ドキュメントプラグインはルートを `/docs`、ブログプラグインは `/blog`、ページプラグインは `/` に配置します。ルート構造は次のようになります。

一致するルートが見つかるまで、すべてのルートはこのネストされたルート設定と照合されます。たとえば、ルート `/docs/configuration` が指定された場合、Docusaurus は最初に `/docs` ブランチに入り、次にドキュメントプラグインによって作成されたサブルートの中から検索します。

`routeBasePath` を変更すると、サイトのルート構造を効果的に変更できます。たとえば、ドキュメントのみモードでは、ドキュメントの `routeBasePath: '/'` を設定すると、ドキュメントプラグインが作成するすべてのルートに `/docs` プレフィックスが付かなくなりますが、他のプラグインによって作成された `/blog` などのサブルートを持つことはできます。

次に、3 つのプラグインが独自の「サブルートのボックス」をどのように構成しているかを見てみましょう。

ページルーティング

ページルーティングは簡単です。ファイルパスは、カスタマイズする方法がなく、URL に直接マッピングされます。詳細については、ページのドキュメントを参照してください。

Markdown ページに使用されるコンポーネントは `@theme/MDXPage` です。React ページは、ルートのコンポーネントとして直接使用されます。

ブログルーティング

ブログは次のルートを作成します

  • **投稿リストページ**: `/`、`/page/2`、`/page/3`...
    • ルートは `pageBasePath` オプションでカスタマイズできます。
    • コンポーネントは `@theme/BlogListPage` です。
  • **投稿ページ**: `/2021/11/21/algolia-docsearch-migration`、`/2021/05/12/announcing-docusaurus-two-beta`...
    • 各 Markdown 投稿から生成されます。
    • ルートは `slug` front matter で完全にカスタマイズできます。
    • コンポーネントは `@theme/BlogPostPage` です。
  • **タグリストページ**: `/tags`
    • ルートは `tagsBasePath` オプションでカスタマイズできます。
    • コンポーネントは `@theme/BlogTagsListPage` です。
  • **タグページ**: `/tags/adoption`、`/tags/beta`...
    • 各投稿の front matter で定義されたタグから生成されます。
    • ルートは常に `tagsBasePath` で定義されたベースを持ちますが、サブルートはタグの `permalink` フィールドでカスタマイズできます。
    • コンポーネントは `@theme/BlogTagsPostsPage` です。
  • **アーカイブページ**: `/archive`
    • ルートは `archiveBasePath` オプションでカスタマイズできます。
    • コンポーネントは `@theme/BlogArchivePage` です。

ドキュメントルーティング

ドキュメントは、**ネストされたルート**を作成する唯一のプラグインです。一番上に、**バージョンパス** `/`、`/next`、`/2.0.0-beta.13`... を登録します。これらは、レイアウトとサイドバーを含むバージョンコンテキストを提供します。これにより、個々のドキュメントを切り替えるときにサイドバーの状態が保持され、同じドキュメントにとどまりながらナビゲーションバーのドロップダウンでバージョンを切り替えることができます。使用されるコンポーネントは `@theme/DocPage` です.

個々のドキュメントは、ナビゲーションバー、フッター、サイドバーなどが `DocPage` コンポーネントによって提供された後の残りのスペースにレンダリングされます。たとえば、このページ `/docs/advanced/routing` は、`./versioned_docs/version-3.5.2/advanced/routing.md` にあるファイルから生成されます。使用されるコンポーネントは `@theme/DocItem` です。

ドキュメントの `slug` front matter はルートの最後の部分をカスタマイズしますが、ベースルートは常にプラグインの `routeBasePath` とバージョンの `path` によって定義されます。

ファイルパスと URL パス

ドキュメント全体を通して、ファイルパスについて話しているのか URL パスについて話しているのかを常に明確にするようにしています。コンテンツプラグインは通常、ファイルパスを URL パスに直接マッピングします。たとえば、`./docs/advanced/routing.md` は `/docs/advanced/routing` になります。ただし、`slug` を使用すると、URL をファイル構造から完全に切り離すことができます。

Markdown でリンクを記述する場合、*ファイルパス* または *URL パス* を意味する可能性があり、Docusaurus はいくつかのヒューリスティックを使用して判別します。

  • パスに `@site` プレフィックスが付いている場合、それは *常に* アセットファイルパスです。
  • パスに `http(s)://` プレフィックスが付いている場合、それは *常に* URL パスです。
  • パスに拡張子が付いていない場合、それは URL パスです。たとえば、URL が `/docs/advanced/routing` のページにあるリンク `[page](../plugins)` は `/docs/plugins` にリンクします。Docusaurus は、サイトをビルドするとき(ルート構造全体がわかっているとき)にのみ壊れたリンクを検出しますが、ファイルの存在については何も想定しません。これは、JSX ファイルで `<a href="../plugins">page</a>` と記述するのと同じです。
  • パスに `.md(x)` 拡張子が付いている場合、Docusaurus はその Markdown ファイルを URL に解決しようと試み、ファイルパスを URL パスに置き換えます。
  • パスに他の拡張子が付いている場合、Docusaurus はそれを アセットとして扱い、バンドルします。

次のディレクトリ構造は、このファイル→ URL マッピングを視覚化するのに役立ちます。どのページにもスラッグのカスタマイズがないと仮定します。

サンプルサイト構造
.
├── blog # blog plugin has routeBasePath: '/blog'
│ ├── 2019-05-28-first-blog-post.md # -> /blog/2019/05/28/first-blog-post
│ ├── 2019-05-29-long-blog-post.md # -> /blog/2019/05/29/long-blog-post
│ ├── 2021-08-01-mdx-blog-post.mdx # -> /blog/2021/08/01/mdx-blog-post
│ └── 2021-08-26-welcome
│ ├── docusaurus-plushie-banner.jpeg
│ └── index.md # -> /blog/2021/08/26/welcome
├── docs # docs plugin has routeBasePath: '/docs'; current version has base path '/'
│ ├── intro.md # -> /docs/intro
│ ├── tutorial-basics
│ │ ├── _category_.json
│ │ ├── congratulations.md # -> /docs/tutorial-basics/congratulations
│ │ └── markdown-features.mdx # -> /docs/tutorial-basics/markdown-features
│ └── tutorial-extras
│ ├── _category_.json
│ ├── manage-docs-versions.md # -> /docs/tutorial-extras/manage-docs-versions
│ └── translate-your-site.md # -> /docs/tutorial-extras/translate-your-site
├── src
│ └── pages # pages plugin has routeBasePath: '/'
│ ├── index.module.css
│ ├── index.tsx # -> /
│ └── markdown-page.md # -> /markdown-page
└── versioned_docs
└── version-1.0.0 # version has base path '/1.0.0'
├── intro.md # -> /docs/1.0.0/intro
├── tutorial-basics
│ ├── _category_.json
│ ├── congratulations.md # -> /docs/1.0.0/tutorial-basics/congratulations
│ └── markdown-features.mdx # -> /docs/1.0.0/tutorial-basics/markdown-features
└── tutorial-extras
├── _category_.json
├── manage-docs-versions.md # -> /docs/1.0.0/tutorial-extras/manage-docs-versions
└── translate-your-site.md # -> /docs/1.0.0/tutorial-extras/translate-your-site

コンテンツプラグインについてはこれくらいです。一歩戻って、Docusaurus アプリケーション全般でルーティングがどのように機能するかについて説明しましょう。

ルートは HTML ファイルになる

Docusaurus はサーバーサイドレンダリングフレームワークであるため、生成されるすべてのルートはサーバーサイドで静的 HTML ファイルにレンダリングされます。Apache2 などの HTTP サーバーの動作に精通している場合は、これがどのように行われるかを理解できるでしょう。ブラウザが `/docs/advanced/routing` ルートにリクエストを送信すると、サーバーはそれを HTML ファイル `/docs/advanced/routing/index.html` に対するリクエストとして解釈し、それを返します。

`/docs/advanced/routing` ルートは、`/docs/advanced/routing/index.html` または `/docs/advanced/routing.html` のいずれかに対応できます。一部のホスティングプロバイダーは、末尾のスラッシュの有無によってそれらを区別し、もう一方を許容しない場合があります。末尾のスラッシュガイド で詳細をご覧ください。

たとえば、上記のディレクトリのビルド出力は(他のアセットと JS バンドルを無視すると)次のようになります。

上記のワークスペースの出力
build
├── 404.html # /404/
├── blog
│ ├── archive
│ │ └── index.html # /blog/archive/
│ ├── first-blog-post
│ │ └── index.html # /blog/first-blog-post/
│ ├── index.html # /blog/
│ ├── long-blog-post
│ │ └── index.html # /blog/long-blog-post/
│ ├── mdx-blog-post
│ │ └── index.html # /blog/mdx-blog-post/
│ ├── tags
│ │ ├── docusaurus
│ │ │ └── index.html # /blog/tags/docusaurus/
│ │ ├── hola
│ │ │ └── index.html # /blog/tags/hola/
│ │ └── index.html # /blog/tags/
│ └── welcome
│ └── index.html # /blog/welcome/
├── docs
│ ├── 1.0.0
│ │ ├── intro
│ │ │ └── index.html # /docs/1.0.0/intro/
│ │ ├── tutorial-basics
│ │ │ ├── congratulations
│ │ │ │ └── index.html # /docs/1.0.0/tutorial-basics/congratulations/
│ │ │ └── markdown-features
│ │ │ └── index.html # /docs/1.0.0/tutorial-basics/markdown-features/
│ │ └── tutorial-extras
│ │ ├── manage-docs-versions
│ │ │ └── index.html # /docs/1.0.0/tutorial-extras/manage-docs-versions/
│ │ └── translate-your-site
│ │ └── index.html # /docs/1.0.0/tutorial-extras/translate-your-site/
│ ├── intro
│ │ └── index.html # /docs/1.0.0/intro/
│ ├── tutorial-basics
│ │ ├── congratulations
│ │ │ └── index.html # /docs/tutorial-basics/congratulations/
│ │ └── markdown-features
│ │ └── index.html # /docs/tutorial-basics/markdown-features/
│ └── tutorial-extras
│ ├── manage-docs-versions
│ │ └── index.html # /docs/tutorial-extras/manage-docs-versions/
│ └── translate-your-site
│ └── index.html # /docs/tutorial-extras/translate-your-site/
├── index.html # /
└── markdown-page
└── index.html # /markdown-page/

`trailingSlash` が `false` に設定されている場合、ビルドは `intro/index.html` ではなく `intro.html` を出力します。

すべての HTML ファイルは絶対 URL を使用して JS アセットを参照するため、正しいアセットを見つけるためには、`baseUrl` フィールドを設定する必要があります。`baseUrl` は、出力されるバンドルのファイル構造には影響しないことに注意してください。ベース URL は、Docusaurus ルーティングシステムの 1 つ上のレベルです。`url` と `baseUrl` の集約を、Docusaurus サイトの実際の場所と考えることができます。

たとえば、出力される HTML には `<link rel="preload" href="/assets/js/runtime~main.7ed5108a.js" as="script">` のようなリンクが含まれます。絶対 URL はホストから解決されるため、バンドルが `https://example.com/base/` パスに配置されている場合、リンクは `https://example.com/assets/js/runtime~main.7ed5108a.js` を指しますが、これは存在しません。ベース URL として `/base/` を指定することにより、リンクは正しく `/base/assets/js/runtime~main.7ed5108a.js` を指します.

ローカライズされたサイトでは、ロケールもベース URL の一部になります。たとえば、`https://docusaurus.dokyumento.jp/zh-CN/docs/advanced/routing/` のベース URL は `/zh-CN/` です。

ルートの生成とアクセス

addRoute ライフサイクルアクションは、ルートを生成するために使用されます。これは、ルートツリーにルート設定の一部を登録し、ルート、コンポーネント、およびコンポーネントが必要とする props を提供します。アーキテクチャの概要で説明されているように、サーバーとクライアントは一時ファイルを通じてのみ通信するため、props とコンポーネントはどちらもバンドラーが require するためのパスとして提供されます。

すべてのルートは .docusaurus/routes.js に集約されており、デバッグプラグインの ルートパネル で表示できます。

クライアント側では、ページのルートにアクセスするために @docusaurus/router を提供しています。 @docusaurus/routerreact-router-dom パッケージの再エクスポートです。たとえば、useLocation を使用して現在のページの ロケーション を取得し、useHistory を使用して 履歴オブジェクト にアクセスできます。(機能は似ていますが、ブラウザ API とは同じではありません。具体的な API については、React Router のドキュメントを参照してください。)

この API は、ブラウザ専用の window.location とは異なり、**SSR セーフ**です。

myComponent.js
import React from 'react';
import {useLocation} from '@docusaurus/router';

export function PageRoute() {
// React router provides the current component's route, even in SSR
const location = useLocation();
return (
<span>
We are currently on <code>{location.pathname}</code>
</span>
);
}
http://localhost:3000
現在 /docs/advanced/routing にいます

SPAリダイレクトからの脱出

Docusaurus は シングルページアプリケーション を構築します。ルート遷移は React Router の history.push() メソッドを介して行われます。この操作はクライアント側で行われます。ただし、ルート遷移がこの方法で発生するための前提条件は、ターゲット URL がルーターに認識されていることです。そうでない場合、ルーターはこのパスをキャッチし、代わりに 404 ページを表示します。

static フォルダーに HTML ページを配置すると、それらはビルド出力にコピーされ、Web サイトの一部としてアクセスできるようになりますが、Docusaurus ルートシステムの一部ではありません。このルートが外部リンクであるかのように、SPA ではない方法でドメインの別の部分にリダイレクトできる pathname:// プロトコルを提供します。

- [pathname:///pure-html](pathname:///pure-html)
http://localhost:3000

pathname:// プロトコルは、静的フォルダー内のコンテンツを参照するのに役立ちます。たとえば、Docusaurus は すべての Markdown 静的アセットを require() 呼び出しに変換しますpathname:// を使用すると、Webpack によってハッシュされるのではなく、通常のリンクのままにすることができます。

my-doc.md
![An image from the static](pathname:///img/docusaurus.png)

[An asset from the static](pathname:///files/asset.pdf)

Docusaurus は、コンテンツを処理せずに pathname:// プレフィックスのみを削除します。