ルーティング
ファイルベースのルーティング
VitePressはファイルベースのルーティングを使用します。これは、生成されるHTMLページがソースのMarkdownファイルのディレクトリ構造からマッピングされることを意味します。たとえば、次のディレクトリ構造が与えられた場合
.
├─ guide
│ ├─ getting-started.md
│ └─ index.md
├─ index.md
└─ prologue.md
生成されるHTMLページは次のようになります
index.md --> /index.html (accessible as /)
prologue.md --> /prologue.html
guide/index.md --> /guide/index.html (accessible as /guide/)
guide/getting-started.md --> /guide/getting-started.html
結果のHTMLは、静的ファイルを配信できる任意のWebサーバーでホストできます。
ルートディレクトリとソースディレクトリ
VitePressプロジェクトのファイル構造には、**プロジェクトルート**と**ソースディレクトリ**という2つの重要な概念があります。
プロジェクトルート
プロジェクトルートは、VitePressが.vitepress
という特別なディレクトリを探す場所です。 .vitepress
ディレクトリは、VitePressの設定ファイル、開発サーバーのキャッシュ、ビルド出力、およびオプションのテーマカスタマイズコードのための予約場所です。
コマンドラインからvitepress dev
またはvitepress build
を実行すると、VitePressは現在の作業ディレクトリをプロジェクトルートとして使用します。サブディレクトリをルートとして指定するには、コマンドに相対パスを渡す必要があります。たとえば、VitePressプロジェクトが./docs
にある場合は、vitepress dev docs
を実行する必要があります
.
├─ docs # project root
│ ├─ .vitepress # config dir
│ ├─ getting-started.md
│ └─ index.md
└─ ...
vitepress dev docs
これは、ソースからHTMLへの次のマッピングになります
docs/index.md --> /index.html (accessible as /)
docs/getting-started.md --> /getting-started.html
ソースディレクトリ
ソースディレクトリは、Markdownソースファイルが配置される場所です。デフォルトでは、プロジェクトルートと同じです。ただし、srcDir
設定オプションで設定できます。
srcDir
オプションは、プロジェクトルートからの相対パスで解決されます。たとえば、srcDir: 'src'
の場合、ファイル構造は次のようになります
. # project root
├─ .vitepress # config dir
└─ src # source dir
├─ getting-started.md
└─ index.md
結果のソースからHTMLへのマッピング
src/index.md --> /index.html (accessible as /)
src/getting-started.md --> /getting-started.html
ページ間のリンク
ページ間のリンクには、絶対パスと相対パスの両方を使用できます。 .md
と.html
の両方の拡張子が機能しますが、VitePressが設定に基づいて最終的なURLを生成できるように、ファイル拡張子を省略するのがベストプラクティスです。
<!-- Do -->
[Getting Started](./getting-started)
[Getting Started](../guide/getting-started)
<!-- Don't -->
[Getting Started](./getting-started.md)
[Getting Started](./getting-started.html)
画像などのアセットへのリンクの詳細については、アセットの取り扱いを参照してください。
VitePress以外のページへのリンク
VitePressによって生成されていないサイト内のページにリンクする場合は、完全なURL(新しいタブで開きます)を使用するか、ターゲットを明示的に指定する必要があります
入力
[Link to pure.html](/pure.html){target="_self"}
出力
注意
Markdownリンクでは、`base`がURLの先頭に自動的に付加されます。これは、ベース外のページにリンクする場合、リンクに`../../pure.html`のようなものが必要になることを意味します(ブラウザによって現在のページからの相対パスで解決されます)。
あるいは、アンカータグ構文を直接使用することもできます
<a href="/pure.html" target="_self">Link to pure.html</a>
クリーンURLの生成
サーバーサポートが必要
VitePressでクリーンURLを提供するには、サーバー側のサポートが必要です。
デフォルトでは、VitePressは受信リンクを.html
で終わるURLに解決します。ただし、一部のユーザーは、.html
拡張子がない「クリーンURL」を好む場合があります。たとえば、example.com/path.html
ではなくexample.com/path
です。
一部のサーバーまたはホスティングプラットフォーム(たとえば、Netlify、Vercel、GitHub Pages)は、リダイレクトなしで、/foo
のようなURLを、存在する場合に/foo.html
にマッピングする機能を提供します
- NetlifyとGitHub Pagesは、デフォルトでこれをサポートしています。
- Vercelでは、
vercel.json
でcleanUrls
オプションを有効にする必要があります。
この機能が利用可能な場合は、VitePress独自のcleanUrls
設定オプションを有効にすることもできます。そうすることで、
- ページ間の受信リンクは、
.html
拡張子なしで生成されます。 - 現在のパスが
.html
で終わる場合、ルーターはクライアント側で拡張子のないパスにリダイレクトを実行します。
ただし、サーバーにそのようなサポートを設定できない場合は、次のディレクトリ構造に手動で頼る必要があります
.
├─ getting-started
│ └─ index.md
├─ installation
│ └─ index.md
└─ index.md
ルートリライト
ソースディレクトリ構造と生成されたページ間のマッピングをカスタマイズできます。複雑なプロジェクト構造を持つ場合に役立ちます。たとえば、複数の`package`を持つ`monorepo`があり、次のようにソースファイルと一緒にドキュメントを配置したいとします。
.
├─ packages
│ ├─ pkg-a
│ │ └─ src
│ │ ├─ pkg-a-code.ts
│ │ └─ pkg-a-docs.md
│ └─ pkg-b
│ └─ src
│ ├─ pkg-b-code.ts
│ └─ pkg-b-docs.md
そして、VitePressページを次のように生成したいとします
packages/pkg-a/src/pkg-a-docs.md --> /pkg-a/index.html
packages/pkg-b/src/pkg-b-docs.md --> /pkg-b/index.html
rewrites
オプションを次のように設定することで、これを達成できます
// .vitepress/config.js
export default {
rewrites: {
'packages/pkg-a/src/pkg-a-docs.md': 'pkg-a/index.md',
'packages/pkg-b/src/pkg-b-docs.md': 'pkg-b/index.md'
}
}
rewrites
オプションは、動的ルートパラメータもサポートしています。上記の例では、多くのパッケージがある場合、すべてのパスをリストするのは冗長になります。すべてが同じファイル構造を持っているとすると、次のように設定を簡素化できます
export default {
rewrites: {
'packages/:pkg/src/(.*)': ':pkg/index.md'
}
}
リライトパスはpath-to-regexp
パッケージを使用してコンパイルされます。より高度な構文については、そのドキュメントを参照してください。
リライトを使用した相対リンク
リライトが有効になっている場合、**相対リンクはリライトされたパスに基づいている必要があります**。たとえば、packages/pkg-a/src/pkg-a-code.md
からpackages/pkg-b/src/pkg-b-code.md
への相対リンクを作成するには、次を使用する必要があります
[Link to PKG B](../pkg-b/pkg-b-code)
動的ルート
単一のMarkdownファイルと動的データを使用して多くのページを生成できます。たとえば、プロジェクト内のすべてのパッケージに対応するページを生成するpackages/[pkg].md
ファイルを作成できます。ここで、[pkg]
セグメントは、各ページを他のページと区別するルート**パラメータ**です。
パスローダーファイル
VitePressは静的サイトジェネレーターであるため、可能なページパスはビルド時に決定する必要があります。したがって、動的ルートページには**必ず** **パスローダーファイル**が付属している必要があります。 packages/[pkg].md
の場合、packages/[pkg].paths.js
(.ts
もサポートされています)が必要です
.
└─ packages
├─ [pkg].md # route template
└─ [pkg].paths.js # route paths loader
パスローダーは、paths
メソッドをデフォルトエクスポートとして持つオブジェクトを提供する必要があります。 paths
メソッドは、params
プロパティを持つオブジェクトの配列を返す必要があります。これらのオブジェクトはそれぞれ、対応するページを生成します。
次の`paths`配列が与えられた場合
// packages/[pkg].paths.js
export default {
paths() {
return [
{ params: { pkg: 'foo' }},
{ params: { pkg: 'bar' }}
]
}
}
生成されるHTMLページは次のようになります
.
└─ packages
├─ foo.html
└─ bar.html
複数のパラメータ
動的ルートには複数のパラメータを含めることができます
ファイル構造
.
└─ packages
├─ [pkg]-[version].md
└─ [pkg]-[version].paths.js
パスローダー
export default {
paths: () => [
{ params: { pkg: 'foo', version: '1.0.0' }},
{ params: { pkg: 'foo', version: '2.0.0' }},
{ params: { pkg: 'bar', version: '1.0.0' }},
{ params: { pkg: 'bar', version: '2.0.0' }}
]
}
出力
.
└─ packages
├─ foo-1.0.0.html
├─ foo-2.0.0.html
├─ bar-1.0.0.html
└─ bar-2.0.0.html
動的なパスの生成
パスローダーモジュールはNode.jsで実行され、ビルド時のみ実行されます。ローカルまたはリモートの任意のデータを使用して、パス配列を動的に生成できます。
ローカルファイルからパスを生成する
import fs from 'fs'
export default {
paths() {
return fs
.readdirSync('packages')
.map((pkg) => {
return { params: { pkg }}
})
}
}
リモートデータからパスを生成する
export default {
async paths() {
const pkgs = await (await fetch('https://my-api.com/packages')).json()
return pkgs.map((pkg) => {
return {
params: {
pkg: pkg.name,
version: pkg.version
}
}
})
}
}
ページ内でのパラメータへのアクセス
パラメータを使用して、各ページに追加データを渡すことができます。 Markdownルートファイルは、$params
グローバルプロパティを介してVue式で現在のページパラメータにアクセスできます
- package name: {{ $params.pkg }}
- version: {{ $params.version }}
useData
ランタイムAPIを介して、現在のページのパラメータにアクセスすることもできます。これは、MarkdownファイルとVueコンポーネントの両方で使用できます
<script setup>
import { useData } from 'vitepress'
// params is a Vue ref
const { params } = useData()
console.log(params.value)
</script>
生のコンテンツのレンダリング
ページに渡されたパラメータは、クライアントのJavaScriptペイロードでシリアル化されるため、パラメータに大量のデータ(リモートCMSからフェッチされた生のMarkdownまたはHTMLコンテンツなど)を渡すことは避ける必要があります。
代わりに、各パスオブジェクトの`content`プロパティを使用して、そのようなコンテンツを各ページに渡すことができます
export default {
async paths() {
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
return posts.map((post) => {
return {
params: { id: post.id },
content: post.content // raw Markdown or HTML
}
})
}
}
次に、次の特別な構文を使用して、コンテンツをMarkdownファイル自体の一部としてレンダリングします
<!-- @content -->