コンテンツへスキップ
Fumadocs

国際化

Next.jsのドキュメントを多言語に対応させます。

Fumadocs CLI

npx @fumadocs/cli init --i18n を実行すると、i18n に対応した新しいドキュメントをセットアップできます。手動で設定する場合は、以下の手順に従ってください。

概要

Next.js と Fumadocs の両方で i18n ルーティングを設定します。

Fumadocs が担当するのは、ドキュメントのコンテンツとサイドバーの i18n です。アプリのその他の部分は、独自の i18n 設定で国際化してください。

next-intl などのライブラリを Fumadocs と組み合わせて使うこともできます。基本については、Next.js の i18n を参照してください。

セットアップ

i18n の設定をファイルに定義します。このガイドでは、@/lib/i18n としてインポートします。

lib/i18n.ts
import { defineI18n } from 'fumadocs-core/i18n';

export const i18n = defineI18n({
  defaultLanguage: 'en',
  languages: ['en', 'cn'],
});

i18n の設定で使用できるオプションについては、こちらを参照してください。

ミドルウェア

ユーザーを適切なロケールへリダイレクトするミドルウェアを作成します。

proxy.ts
import { createI18nMiddleware } from 'fumadocs-core/i18n/middleware';
import { i18n } from '@/lib/i18n';

export default createI18nMiddleware(i18n);

export const config = {
  // Matcher ignoring `/_next/` and `/api/`
  // You may need to adjust it to ignore static assets in `/public` folder
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

独自のミドルウェアを使う場合

デフォルトのミドルウェアの使用は任意です。独自のミドルウェアや、i18n ライブラリが提供するミドルウェアを使うこともできます。

その場合は、ミドルウェアの動作が i18n の設定で指定した hideLocale オプションと整合していることを確認してください。

ルーティング

/app/[lang] フォルダーを作成し、ルートハンドラー以外のページとレイアウトをすべてその中に移動してください。

api/search/route.ts
layout.tsx
(home)/page.tsx
...

よくある間違い

スタイルが消えてしまっていませんか?global.css のインポートパスが正しいままか確認してください。

翻訳

翻訳は lib/layout.shared.tsx で定義します。公式の言語パックなど、詳しくは翻訳を参照してください。

また、baseOptions() に locale パラメーターを追加すると、ロケールごとにレイアウトオプションを切り替えられます。

lib/layout.shared.tsx
import { i18n } from '@/lib/i18n';
import { uiTranslations } from 'fumadocs-ui/i18n';
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';

export const translations = i18n
  .translations()
  .extend(uiTranslations())
  .add({
    en: {
      displayName: 'English',
    },
    cn: {
      displayName: 'Chinese',
    },
  });

export function baseOptions(): BaseLayoutProps { 
export function baseOptions(locale: string): BaseLayoutProps { 
  return {
    // `locale` に応じて異なる props を指定
  };
}

翻訳を <RootProvider /> に渡します。

app/[lang]/layout.tsx
import { RootProvider } from 'fumadocs-ui/provider/next';
import { i18nProvider } from 'fumadocs-ui/i18n';
import { translations } from '@/lib/layout.shared';

export default function Layout({ children }: LayoutProps<'/'>) { 
export default async function Layout({ params, children }: LayoutProps<'/[lang]'>) {
  const { lang } = await params;

  return (
    <html lang={lang} suppressHydrationWarning>
      <body className="flex flex-col min-h-screen">
        <RootProvider
          i18n={i18nProvider(translations, lang)}
        >
          {children}
        </RootProvider>
      </body>
    </html>
  );
}

ロケールを渡す

ページとレイアウトで、ロケールを Fumadocs に渡します。

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

export const source = loader({
  i18n, 
  // その他のオプション
});

動的セグメントに lang 以外の名前を使用する場合

app/[locale] のように別の名前を使用している場合は、docs ページの generateStaticParams() も更新する必要があります。

export function generateStaticParams() {
  return source.generateParams(); 
  return source.generateParams('slug', 'locale'); 
}

使用している検索ソリューションで i18n を設定してください。

  • 組み込み検索: 国際化を参照してください。
  • クラウドソリューション(Algolia など): 多くの場合、多言語対応が公式にサポートされています。

ドキュメントの作成

特定のロケール向けのページを作成する方法については、i18n ルーティングを参照してください。

Fumadocs がナビゲーションを処理するのは、Fumadocs 自身のレイアウト(サイドバーなど)のみです。

それ以外の場所では、useParams フックで URL からロケールを取得し、href の先頭に付加してください。

import Link from 'next/link';
import { useParams } from 'next/navigation';

const { lang } = useParams();

return <Link href={`/${lang}/another-page`}>This is a link</Link>;

fumadocs-core/dynamic-link コンポーネントは動的な href に対応しているため、Markdown/MDX コンテンツ内でロケールのプレフィックスを付加する際に利用できます。

content.mdx
import { DynamicLink } from 'fumadocs-core/dynamic-link';

<DynamicLink href="/[lang]/another-page">This is a link</DynamicLink>

How is this guide?

最終更新日