コンテンツへスキップ
Fumadocs

ローダー API

コンテンツソースを統一されたインターフェースに変換します

機能

loader() は、Fumadocs をさまざまなコンテンツソースと統合するためのインターフェースを提供します。

重要な注意点

  • loader() はサーバーサイドの API です。ビルド時に動作する特殊な仕組みではなく、ブラウザで使える API でもありません。
  • インメモリストレージを使用し、ファイルはコンテンツソースから渡されます。

使い方

Fumadocs MDX などのコンテンツソースと組み合わせて使用できます。詳しくは source を参照してください。

import { loader } from 'fumadocs-core/source';
import { docs } from 'collections/server';

export const source = loader({
  source: docs.toFumadocsSource(),
  baseUrl: '/docs',
});

URL

ベースURLを上書きしたり、各ページのURLを生成する関数を指定したりできます。

import { loader } from 'fumadocs-core/source';

loader({
  baseUrl: '/docs',
  // または関数でカスタマイズすることもできます
  url(slugs, locale) {
    if (locale) return '/' + [locale, 'docs', ...slugs].join('/');
    return '/' + ['docs', ...slugs].join('/');
  },
});

スラッグ

ページファイルからスラッグを生成するカスタム関数を定義できます。

import { loader } from 'fumadocs-core/source';

loader({
  slugs(file, next) {
    console.log(file.path, file.data);
    // `next()` を使うと、デフォルトのスラッグを基に生成できます
    if (file.path.startsWith('blog/')) return ['blog', ...next()];
    // または、`undefined` を返すとデフォルト値にフォールバックします
    return ['my', 'slug'];
  },
});

アイコン

ページファイルとメタファイルで指定された icon プロパティを読み込みます。

import { loader } from 'fumadocs-core/source';
import { icons } from 'lucide-react';
import { createElement } from 'react';

loader({
  icon(icon) {
    if (!icon) {
      // ここでデフォルトのアイコンを設定することもできます
      return;
    }

    if (icon in icons) return createElement(icons[icon as keyof typeof icons]);
  },
});

I18n

i18n の設定をローダーに渡します。

lib/source.ts
import { i18n } from '@/lib/i18n';
import { loader } from 'fumadocs-core/source';

export const source = loader({
  i18n, 
});

i18n を有効にすると、ローダーはロケールごとにページツリーを生成します。

ページの翻訳が存在しない場合は、fallbackLanguage にフォールバックします。

出力

コンテンツローダーのインスタンスを出力します。

ページの取得

スラッグを指定してページを取得します。

import { source } from '@/lib/source';

source.getPage(['slug', 'of', 'page']);

// i18n を使用する場合
source.getPage(['slug', 'of', 'page'], 'locale');

カスタム props

読者が選択したバージョンなど、ページのコンテンツに props を渡せます。コンテンツ側では、パスパラメーターと同じように props として受け取ります:

import { source } from '@/lib/source';

const page = source.getPage(['slug', 'of', 'page'], {
  props: { version: 'v2' },
  // i18n を使う場合
  language: 'locale',
});

ページデータは、コンテンツや目次を含め、これらの props から生成されます。MDX コンポーネントも props として扱われます。処理済みの Markdown で独自のコンポーネントをレンダリングするには、これらを渡してください。

import { getMDXComponents } from '@/components/mdx';

const page = source.getPage(['slug', 'of', 'page'], {
  props: { components: getMDXComponents() },
});
const markdown = await page.data.getText('processed');

補足

検索ルートと LLM ルートは getPages() からページを読み込みますが、これらのページが持つのはパスの params だけです。検索や LLM に認識させたいバリアントは、パスの param として定義する必要があります。

ページの取得

指定したロケールで利用可能なページの一覧を取得します。

import { source } from '@/lib/source';

// すべてのロケールから取得
source.getPages();

// 特定のロケールから取得
source.getPages('locale');

ページツリー

import { source } from '@/lib/source';

// i18n なしの場合
source.getPageTree();

// i18n ありの場合
source.getPageTree('locale');

ノードから取得する

ページツリーのノードには、元のファイルパスへの参照が含まれています。 ツリーのノードから、元のページファイルやメタファイルを取得できます。

import { source } from '@/lib/source';

source.getNodePage(pageNode);
source.getNodeMeta(folderNode);

Params

ページを事前レンダリングするために、全ページのパスパラメータを生成します。 生成されるパラメータ名は slug: string[] と lang: string(i18n 使用時のみ)です。

app/docs/[[...slug]]/page.tsx
import { source } from '@/lib/source';

export function generateStaticParams() {
  return source.generateParams();
}

React Router と TanStack Start は URL 単位でプリレンダリングを行うため、代わりに source.getPages() の url を列挙してください。

言語エントリ

利用可能な言語と、各言語のページを取得します。

import { source } from '@/lib/source';

// 言語 -> ページ
const entries = source.getLanguages();

クライアント API

ローダー API は RSC 環境での利用に最適です。RSC 環境では、サーバーとクライアントの境界を越えて JSX ノードを渡せます。

RSC 以外の環境向けには、軽量なシリアライズレイヤーが用意されています。

import { source } from '@/lib/source';

// ローダーデータを渡す箇所
async function loader() {
  const pageTree = source.getPageTree();

  return {
    pageTree: await source.serializePageTree(pageTree),
  };
}

動的ローダー

dynamicLoader() は、コンテンツソースに再検証のための追加機能を提供します。動的ソースと組み合わせて使用してください。

import { dynamicLoader } from 'fumadocs-core/source';
import { createMySource } from './my-source';

const source = dynamicLoader(createMySource(), {
  baseUrl: '/docs',
});

export async function getSource() {
  return source.get();
}

await source.get() を呼び出すと、通常のコンテンツローダーオブジェクトが返されます。

const docs = await getSource();

const page = docs.getPage(['...']);

再検証

動的ソースはローダーによってキャッシュされます。

ソースの内容が時間とともに変わる場合は、invalidate() を呼び出してキャッシュをクリアするか、revalidate() を呼び出してキャッシュを更新してください。

source.invalidate();

await source.revalidate();

マルチソース構成では、特定のソースだけを無効化または再検証できます。

source.invalidate('docs');

await source.revalidate('docs');

How is this guide?

最終更新日