カスタムテーマの使用
テーマの解決
.vitepress/theme/index.js
または .vitepress/theme/index.ts
ファイル(「テーマエントリファイル」)を作成することで、カスタムテーマを有効にできます。
.
├─ docs # project root
│ ├─ .vitepress
│ │ ├─ theme
│ │ │ └─ index.js # theme entry
│ │ └─ config.js # config file
│ └─ index.md
└─ package.json
テーマエントリファイルの存在を検出すると、VitePressは常にデフォルトテーマの代わりにカスタムテーマを使用します。ただし、デフォルトテーマを拡張することで、さらに高度なカスタマイズを行うことができます。
テーマインターフェース
VitePressのカスタムテーマは、次のインターフェースを持つオブジェクトとして定義されます。
interface Theme {
/**
* Root layout component for every page
* @required
*/
Layout: Component
/**
* Enhance Vue app instance
* @optional
*/
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
/**
* Extend another theme, calling its `enhanceApp` before ours
* @optional
*/
extends?: Theme
}
interface EnhanceAppContext {
app: App // Vue app instance
router: Router // VitePress router instance
siteData: Ref<SiteData> // Site-level metadata
}
テーマエントリファイルは、テーマをデフォルトエクスポートとしてエクスポートする必要があります。
// .vitepress/theme/index.js
// You can directly import Vue files in the theme entry
// VitePress is pre-configured with @vitejs/plugin-vue.
import Layout from './Layout.vue'
export default {
Layout,
enhanceApp({ app, router, siteData }) {
// ...
}
}
デフォルトエクスポートはカスタムテーマの唯一の契約であり、Layout
プロパティのみが必須です。そのため、技術的には、VitePressテーマは単一のVueコンポーネントだけにすることも可能です。
レイアウトコンポーネント内では、通常のVite + Vue 3アプリケーションと同様に動作します。テーマはSSRと互換性がある必要があることにも注意してください。
レイアウトの作成
最も基本的なレイアウトコンポーネントには、<Content />
コンポーネントを含める必要があります。
<!-- .vitepress/theme/Layout.vue -->
<template>
<h1>Custom Layout!</h1>
<!-- this is where markdown content will be rendered -->
<Content />
</template>
上記のレイアウトは、すべてのページのMarkdownをHTMLとしてレンダリングするだけです。最初の改善として、404エラーを処理できます。
<script setup>
import { useData } from 'vitepress'
const { page } = useData()
</script>
<template>
<h1>Custom Layout!</h1>
<div v-if="page.isNotFound">
Custom 404 page!
</div>
<Content v-else />
</template>
useData()
ヘルパーは、条件付きで異なるレイアウトをレンダリングするために必要なすべてのランタイムデータを提供します。アクセスできる他のデータの1つは、現在のページのフロントマターです。これにより、エンドユーザーは各ページのレイアウトを制御できます。たとえば、ユーザーは、次の記述でページが特別なホームページレイアウトを使用する必要があることを示すことができます。
---
layout: home
---
そして、このテーマを調整することができます。
<script setup>
import { useData } from 'vitepress'
const { page, frontmatter } = useData()
</script>
<template>
<h1>Custom Layout!</h1>
<div v-if="page.isNotFound">
Custom 404 page!
</div>
<div v-if="frontmatter.layout === 'home'">
Custom home page!
</div>
<Content v-else />
</template>
もちろん、レイアウトを複数のコンポーネントに分割することもできます。
<script setup>
import { useData } from 'vitepress'
import NotFound from './NotFound.vue'
import Home from './Home.vue'
import Page from './Page.vue'
const { page, frontmatter } = useData()
</script>
<template>
<h1>Custom Layout!</h1>
<NotFound v-if="page.isNotFound" />
<Home v-if="frontmatter.layout === 'home'" />
<Page v-else /> <!-- <Page /> renders <Content /> -->
</template>
テーマコンポーネントで使用できるすべてのものについては、ランタイムAPIリファレンスを参照してください。さらに、ビルド時データの読み込みを利用して、データ駆動型レイアウト(たとえば、現在のプロジェクトのすべてのブログ投稿を一覧表示するページ)を生成できます。
カスタムテーマの配布
カスタムテーマを配布する最も簡単な方法は、GitHub上のテンプレートリポジトリとして提供することです。
テーマをnpmパッケージとして配布する場合は、次の手順に従ってください。
テーマオブジェクトをパッケージエントリのデフォルトエクスポートとしてエクスポートします。
該当する場合は、テーマ設定の型定義を
ThemeConfig
としてエクスポートします。テーマでVitePressの設定を調整する必要がある場合は、その設定をパッケージのサブパス(例:
my-theme/config
)にエクスポートして、ユーザーが拡張できるようにします。テーマ設定オプションを(設定ファイルとフロントマターの両方で)文書化します。
テーマの使用方法に関する明確な指示を提供します(下記参照)。
カスタムテーマの使用
外部テーマを使用するには、カスタムテーマエントリからインポートして再エクスポートします。
// .vitepress/theme/index.js
import Theme from 'awesome-vitepress-theme'
export default Theme
テーマを拡張する必要がある場合
// .vitepress/theme/index.js
import Theme from 'awesome-vitepress-theme'
export default {
extends: Theme,
enhanceApp(ctx) {
// ...
}
}
テーマで特別なVitePress設定が必要な場合は、独自の構成でも拡張する必要があります。
// .vitepress/config.ts
import baseConfig from 'awesome-vitepress-theme/config'
export default {
// extend theme base config (if needed)
extends: baseConfig
}
最後に、テーマがテーマ設定の型を提供する場合
// .vitepress/config.ts
import baseConfig from 'awesome-vitepress-theme/config'
import { defineConfigWithTheme } from 'vitepress'
import type { ThemeConfig } from 'awesome-vitepress-theme'
export default defineConfigWithTheme<ThemeConfig>({
extends: baseConfig,
themeConfig: {
// Type is `ThemeConfig`
}
})