コンテンツへスキップ
Fumadocs

リンクの検証

リンクが正しいかどうかを検証します。

セットアップ

next-validate-link を使うと、コンテンツファイル内のリンクを検証できます。

このガイドは主に Fumadocs MDX を対象としています。その他の構成については next-validate-link のドキュメントを参照してください。

アプリのルートをスキャンするスクリプトを作成します。populate には docs ルートの params を列挙します。

scripts/lint.ts
import { type FileObject, printErrors, scanURLs, validateFiles } from 'next-validate-link';
import { source } from '@/lib/source';

const scanned = await scanURLs({
  preset: 'tanstack-start',
  populate: {
    // 非同期コレクションでは、目次はコンテンツと一緒に読み込まれます
    'docs/[[..._splat]]': await Promise.all(
      source.getPages().map(async (page) => ({
        value: { _splat: page.slugs },
        hashes: getHeadings(await page.data.load()),
      })),
    ),
  },
});

同じスクリプト内で、スキャンした URL を基にコンテンツファイルを検証します。

scripts/lint.ts
import type { TOCItemType } from 'fumadocs-core/toc';

printErrors(
  await validateFiles(await getFiles(), {
    scanned,
    // 各種 MDX コンポーネントの `href` 属性をチェック
    markdown: {
      components: {
        Card: { attributes: ['href'] },
      },
    },
    // 相対パスをチェック
    checkRelativePaths: 'as-url',
  }),
  true,
);

function getHeadings({ toc }: { toc: TOCItemType[] }): string[] {
  return toc.map((item) => item.url.slice(1));
}

function getFiles() {
  const promises = source.getPages().map(async (page): Promise<FileObject> => ({
    path: page.absolutePath,
    content: await page.data.getText('raw'),
    url: page.url,
    data: page.data,
  }));

  return Promise.all(promises);
}

Lint の実行

アプリのランタイム外から source オブジェクトにアクセスするには、Bun 用に Fumadocs MDX Loader を設定してください。

その後、スクリプトを実行してリンクを検証します。

bun ./scripts/lint.ts

Node.js ローダー

TypeScript のトランスパイル設定(または新しいバージョンの Node.js)と、Fumadocs MDX Loader の設定が必要になる場合があります。

特別な理由がなければ、Bun または tsx を使うほうが手軽です。

How is this guide?

最終更新日