コンテンツへスキップ
Fumadocs

国際化

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

Fumadocs CLI

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

概要

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

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

セットアップ

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

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

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

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

ルーティング

ページに [...lang] プレフィックスを追加します。レストパラメーターを使うことで、デフォルト言語をプレフィックスなし (例: /docs) で扱えます。

index.astro
[...slug].astro
search.ts

Fumadocs が生成する URL をこれらのルートと一致させるため、hideLocale を有効にします。

src/lib/i18n.ts
export const i18n = defineI18n({
  defaultLanguage: 'en',
  languages: ['cn', 'en'],
  hideLocale: 'default-locale', 
});

翻訳

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

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

src/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());

export function baseOptions(): BaseLayoutProps { 
export function baseOptions(locale: string): BaseLayoutProps { 
  return {
    nav: {
      title: 'My App',
      url: locale === i18n.defaultLanguage ? '/' : `/${locale}`, 
    },
  };
}

翻訳を <Provider /> に渡します。MDX コンテンツはそれ自体が独立したアイランドなので、こちらにもプロバイダーが必要です。

import { navigate } from 'astro:transitions/client';
import type { ReactNode } from 'react';
import { RootProvider } from 'fumadocs-ui/provider/astro';
import { i18nProvider } from 'fumadocs-ui/i18n';
import { translations } from '@/lib/layout.shared';
import SearchDialog from '@/components/search';

export interface ProviderProps {
  lang: string; 
  pathname: string;
  params: Record<string, string | undefined>;
  children?: ReactNode;
}

export function Provider({ lang, pathname, params, children }: ProviderProps) {
  return (
    <RootProvider
      pathname={pathname}
      params={params}
      navigate={navigate}
      i18n={i18nProvider(translations, lang)}
      search={{ SearchDialog }}
    >
      {children}
    </RootProvider>
  );
}

/**
 * MDX コンテンツ用(それ自体が独立したアイランドのため)。
 */
export function ContentProvider({ lang, pathname, params, children }: ProviderProps) {
  return (
    <RootProvider
      pathname={pathname}
      params={params}
      navigate={navigate}
      i18n={i18nProvider(translations, lang)}
      theme={{ enabled: false }}
      search={{ enabled: false }}
    >
      {children}
    </RootProvider>
  );
}

ロケールを渡す

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

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

export const source = loader({
  source: toFumadocsSource(await getCollection('docs'), await getCollection('meta')),
  baseUrl: '/docs',
  i18n, 
});

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

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

ドキュメントの作成

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

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

それ以外の場所では、Astro.params またはパスからロケールを取り出し、リンクの先頭に付加してください。

---
const { lang } = Astro.params;
---

<a href={lang ? `/${lang}/about` : '/about'}>About Us</a>

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

MDX コンテンツはコンポーネントを独自のアイランド内でレンダリングするため、MDX コンポーネントに追加してください。

src/components/mdx.tsx
import { DynamicLink } from 'fumadocs-core/dynamic-link'; 

export function getMDXComponents(components?: MDXComponents) {
  return {
    ...defaultMdxComponents,
    DynamicLink, 
    ...components,
  } satisfies MDXComponents;
}
content.mdx
<DynamicLink href="/[lang]/another-page">This is a link</DynamicLink>

How is this guide?

最終更新日