跳至內容
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] 前綴。透過 rest 參數,預設語言可以不帶前綴 (例如 /docs) 。

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

啟用 hideLocale,讓 Fumadocs 產生的 URL 與這些路由一致:

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 內容自成一個獨立的 island,因此也需要提供 provider:

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 內容使用,因為它自成一個獨立的 island。
 */
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 只會處理其自身版面配置 (例如側邊欄) 中的導覽。

至於其他地方,請從 Astro.params 或路徑中擷取語系,並將其加在連結的開頭。

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

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

fumadocs-core/dynamic-link 元件支援動態 href,因此您可以在 Markdown/MDX 內容中用它加上語系前綴。

由於 MDX 內容會在其自身的 island 中算繪這些元件,請將它加入您的 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?

最後更新於