ローカル HTML
ローカルの HTML ファイルを扱うコンテンツソースです。
はじめに
@fumadocs/local-html は、ローカルの HTML ファイル用のコンテンツソースです。バンドラーを使わない設計のため、完全にランタイムで動作します。
自分で執筆するのではなく、HTML として受け取るページを対象としています。たとえば、エクスポートしたスライドやレポート、他のツールの出力などです。各ファイルはそのままの形でレンダリングされるのではなく、ドキュメントのテーマに合わせて変換されます。
ローカル Markdown とは異なり、HTML は執筆に使うドキュメント形式ではなく、変換対象のデータとして扱われます。
制限事項
- スクリプトは除去されるため、元のページのインタラクティブな動作は再現されません。
- コンテンツ内で MDX コンポーネントは使用できませんが、レンダリング時に HTML タグをコンポーネントにマッピングできます。
- この処理は変換であり、サニタイズではありません。実行されるものは一切残りませんが、残ったマークアップはそのままレンダリングされ、そこで参照されているリソース (特に画像) は、ページを開いたすべてのユーザーの環境で読み込まれます。コンテンツディレクトリには、Markdown コンテンツなど、信頼できるファイルだけを置いてください。
セットアップ
パッケージをインストールします。
npm install @fumadocs/local-htmllocalHtml インスタンスを作成し、Fumadocs に接続します。
import { dynamicLoader } from 'fumadocs-core/source';
import { localHtml } from '@fumadocs/local-html';
const pages = localHtml({
dir: 'content/pages',
// オプション
});
const pagesLoader = dynamicLoader(pages.dynamicSource(), {
baseUrl: '/docs',
});
export async function getSource() {
return pagesLoader.get();
}pagesLoader.get() から返されるソースは、通常のコンテンツローダーのインスタンスです。
使い方
page.data.load() は、処理済みコンテンツのレンダラーを返します。
ページ内でレンダリングします。
import type { ReactNode } from 'react';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { getSource } from '@/lib/source';
export default async function Layout({ children }: { children: ReactNode }) {
const source = await getSource();
return <DocsLayout tree={source.getPageTree()}>{children}</DocsLayout>;
}render() にコンポーネントを渡すと、HTML タグをアンカー付きの見出しなどの独自コンポーネントに置き換えられます。
import { getMDXComponents } from '@/components/mdx';
const { body, toc } = await renderer.render(getMDXComponents());ページのメタデータ
各ページのタイトルと説明は、そのページの <head> から読み取られます。
<title>がページのタイトルになります。<meta name="description">が説明になります。
fumadocs: の meta タグを使用すると、表示されるコンテンツを変更せずにこれらを上書きできます (アイコンの設定も可能です) 。
<meta name="fumadocs:title" content="My Page" />
<meta name="fumadocs:description" content="A short description." />
<meta name="fumadocs:icon" content="SquareBookmark" />ドキュメント内のすべての <meta name>/content のペアは、page.data.metadata からも参照できます。
他のローカルソースと同様に、meta.json ファイルでページツリーをカスタマイズでき、その内容は metaSchema で検証されます。
コンテンツオプション
ページからはコンテンツ要素のみが抽出されます。唯一の <main> があればそれを、なければ唯一の <article> を使用し、どちらもない場合は <header> や <nav> などのページ装飾部分を取り除いた <body> にフォールバックします。テーマの本文用スタイル (prose) が適用されるよう、この要素の class 属性と style 属性は削除されます。また、目次と検索に利用できるよう、見出しには id が付与されます。
これらの動作はそれぞれ設定で変更できます。
import { localHtml } from '@fumadocs/local-html';
const pages = localHtml({
dir: 'content/pages',
// テーマに合わせて調整せず、元の class/style 属性を保持する
adaptStyles: false,
// 指定したタグもコンテンツから除外する
exclude: ['aside'],
// ページコンテンツを含む要素を選ぶカスタムロジック
selectContent: (root) => {
// hast 要素を返す(デフォルトの動作にする場合は undefined を返す)
},
});シンタックスハイライト
<pre><code> ブロックは Shiki によってハイライトされます。オプションは ローカル Markdown と同じものが使用されます。
const pages = localHtml({
dir: 'content/pages',
rehypeCodeOptions: {
themes: {
light: 'github-light',
dark: 'github-dark',
},
},
});言語は、ブロックの <code> 要素、またはそれを囲む <pre> 要素に付与された language-* クラスから判別されます。
<pre><code class="language-ts">const answer: number = 42;</code></pre>言語が指定されていないブロックは、プレーンテキストとして表示されます。シンタックスハイライトを無効にするには、rehypeCodeOptions: false を渡してください。
ホットリロード
@fumadocs/local-html はランタイムにファイルを読み込むため、デフォルトではファイルの変更を監視しません。
開発中は、Vite プラグインが Vite のファイルウォッチャーを使ってソースを無効化するため、追加のプロセスやポートは必要ありません。設定ファイルにプラグインを追加し、ソースを接続してください。
import { defineConfig } from 'waku/config';
import { localContentPlugin } from '@fumadocs/local-html/dev/vite';
export default defineConfig({
vite: {
plugins: [localContentPlugin()],
},
});独自のウォッチャーを使う場合は、ファイルの変更時に pages.invalidateFile(path) を呼び出してください。
再検証を無効にする
再検証が不要で、一度きりのスナップショットだけが必要な場合は、staticSource() を使用できます。
dynamicLoader() だけでなく、通常の loader() でも使用できます。
import { loader } from 'fumadocs-core/source';
import { localHtml } from '@fumadocs/local-html';
const pages = localHtml({
dir: 'content/pages',
});
export const source = loader(await pages.staticSource(), {
baseUrl: '/docs',
});How is this guide?
最終更新日
