跳转到内容
Filters

    国际化 (i18n)

    Starlight 提供了内置的多语言支持,包括路由、回退内容和完整的从右到左(RTL)语言支持。

    1. 通过将 localesdefaultLocale 传递给 Starlight 集成,告诉 Starlight 你支持的语言:

      astro.config.mjs
      import { defineConfig } from 'astro/config';
      import starlight from '@astrojs/starlight';
      export default defineConfig({
      integrations: [
      starlight({
      title: '我的文档',
      // 为此网站设置英语为默认语言。
      defaultLocale: 'en',
      locales: {
      // 英文文档在 `src/content/docs/en/` 中。
      en: {
      label: 'English',
      },
      // 简体中文文档在 `src/content/docs/zh-cn/` 中。
      'zh-cn': {
      label: '简体中文',
      lang: 'zh-CN',
      },
      // 阿拉伯文档在 `src/content/docs/ar/` 中。
      ar: {
      label: 'العربية',
      dir: 'rtl',
      },
      },
      }),
      ],
      });

      你的 defaultLocale 将用于回退内容和 UI 标签,所以选择你最有可能开始编写内容的语言,或者已经有内容的语言。

    2. src/content/docs/ 中为每种语言创建一个目录。 例如,对于上面显示的配置,创建以下文件夹:

      • 文件夹src/
        • 文件夹content/
          • 文件夹docs/
            • 文件夹ar/
            • 文件夹en/
            • 文件夹zh-cn/
    3. 现在你可以在你的语言目录中添加内容文件。使用相同的文件名来关联跨语言的页面,并利用 Starlight 的完整的 i18n 功能,包括回退内容、翻译通知等。

      举个例子,创建 ar/index.mden/index.md 来分别表示阿拉伯语和英语的主页。

    对于更高级的 i18n 场景,Starlight 也支持使用 Astro 的 i18n 配置选项来配置国际化。

    你可以使用“root”语言来提供没有任何 i18n 前缀的语言。例如,如果英语是你的 root 语言,那么英语页面的路径将是 /about 而不是 /en/about

    要设置 root 语言,请在你的 locales 配置中使用 root 键。如果 root 语言也是你的内容的默认语言,请删除 defaultLocale 或将其设置为 'root'

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import starlight from '@astrojs/starlight';
    export default defineConfig({
    integrations: [
    starlight({
    title: '我的文档',
    defaultLocale: 'root', // 可选
    locales: {
    root: {
    label: 'English',
    lang: 'en', // lang 是 root 语言必须的
    },
    'zh-cn': {
    label: '简体中文',
    lang: 'zh-CN',
    },
    },
    }),
    ],
    });

    当使用 root 语言时,将页面直接放在 src/content/docs/ 中,而不是在专用的语言文件夹中。例如,当使用上面的配置时,这里是英语和中文的主页文件:

    • 文件夹src/
      • 文件夹content/
        • 文件夹docs/
          • index.md
          • 文件夹zh-cn/
            • index.md

    默认情况下,Starlight 是一个单语言(英语)网站。要在其他语言中创建单语言网站,请将其设置为 locales 配置中的 root

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import starlight from '@astrojs/starlight';
    export default defineConfig({
    integrations: [
    starlight({
    title: 'My Docs',
    locales: {
    root: {
    label: '简体中文',
    lang: 'zh-CN',
    },
    },
    }),
    ],
    });

    这允许你在不启用其他多语言网站的国际化功能的情况下,覆盖 Starlight 的默认语言,例如语言选择器。

    Starlight 期望你在所有语言中创建等效的页面。例如,如果你有一个 en/about.md 文件,请为你支持的每种其他语言创建一个 about.md。这允许 Starlight 为尚未翻译的页面提供自动回退内容。

    如果某种语言尚未提供翻译,Starlight 将为读者显示该页面的默认语言(通过 defaultLocale 设置)的内容。例如,如果你尚未创建关于你的法语版本,并且你的默认语言是英语,那么访问 /fr/about 的访问者将看到来自 /en/about 的英语内容,并显示该页面尚未翻译的通知。这有助于你在默认语言中添加内容,然后在翻译人员有时间时逐步翻译它。

    默认情况下,Starlight 会为所有语言使用相同的站点标题。 如果你需要为每种语言自定义标题,你可以在 Starlight 的选项中将一个对象传递给 title

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import starlight from '@astrojs/starlight';
    export default defineConfig({
    integrations: [
    starlight({
    title: 'My Docs',
    title: {
    en: 'My Docs',
    'zh-CN': '我的文档',
    },
    defaultLocale: 'en',
    locales: {
    en: { label: 'English' },
    'zh-cn': { label: '简体中文', lang: 'zh-CN' },
    },
    }),
    ],
    });

    除了托管翻译的内容文件之外,Starlight 还允许你翻译默认的 UI 字符串(例如,目录中的“本页”标题),以便你的读者可以完全使用所选的语言体验你的网站。

    默认提供了阿拉伯语、波兰语、波斯语、丹麦语、德语、俄语、法语、芬兰语、韩语、荷兰语、加利西亚语、加泰罗尼亚语、捷克语、拉脱维亚语、罗马尼亚语、葡萄牙语、日语、瑞典语、书面挪威语、斯洛伐克语、土耳其语、乌克兰语、西班牙语、希伯来语、匈牙利语、意大利语、印地语、印度尼西亚语、英语、越南语、中文和中文(台湾)的翻译 UI 字符串, 同时我们欢迎贡献添加更多默认语言

    你可以通过 i18n 数据集合提供你支持的其他语言的翻译 - 或覆盖我们的默认标签。

    1. 如果尚未配置,请在 src/content.config.ts 中配置 i18n 数据集合:

      src/content.config.ts
      import { defineCollection } from 'astro:content';
      import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders';
      import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';
      export const collections = {
      docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
      i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() }),
      };
    2. 为你想要提供 UI 翻译字符串的每种其他语言在 src/content/i18n/ 中创建一个 JSON 文件。 例如,这将为阿拉伯语和简体中文添加翻译文件:

      • 文件夹src/
        • 文件夹content/
          • 文件夹i18n/
            • ar.json
            • zh-CN.json
    3. 在 JSON 文件中添加你想要翻译的键的翻译。只翻译值,将键保留为英语(例如 "search.label": "搜索")。

      这些是 Starlight 附带的现有字符串的英文默认值:

      {
      "skipLink.label": "Skip to content",
      "search.label": "Search",
      "search.ctrlKey": "Ctrl",
      "search.cancelLabel": "Cancel",
      "search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
      "search.pagefind.clear": "Clear",
      "search.pagefind.filters": "Filters",
      "search.pagefind.loadMore": "Load more results",
      "search.pagefind.client.searching": "Searching for {{query}}…",
      "search.pagefind.client.results_zero": "No results for {{query}}",
      "search.pagefind.client.results_one": "{{count}} result for {{query}}",
      "search.pagefind.client.results_other": "{{count}} results for {{query}}",
      "themeSelect.accessibleLabel": "Select theme",
      "themeSelect.dark": "Dark",
      "themeSelect.light": "Light",
      "themeSelect.auto": "Auto",
      "languageSelect.accessibleLabel": "Select language",
      "menuButton.accessibleLabel": "Menu",
      "sidebarNav.accessibleLabel": "Main",
      "tableOfContents.onThisPage": "On this page",
      "tableOfContents.overview": "Overview",
      "i18n.untranslatedContent": "This content is not available in your language yet.",
      "page.editLink": "Edit page",
      "page.lastUpdated": "Last updated:",
      "page.previousLink": "Previous",
      "page.nextLink": "Next",
      "page.draft": "This content is a draft and will not be included in production builds.",
      "404.text": "Page not found. Check the URL or try using the search bar.",
      "aside.note": "Note",
      "aside.tip": "Tip",
      "aside.caution": "Caution",
      "aside.danger": "Danger",
      "fileTree.directory": "Directory",
      "builtWithStarlight.label": "Built with Starlight",
      "heading.anchorLabel": "Section titled “{{title}}”"
      }

      Starlight 的代码块使用了 Expressive Code。 你可以在同一个 JSON 文件中使用 expressiveCode 键来设置它的 UI 字符串翻译。

      {
      "expressiveCode.copyButtonCopied": "Copied!",
      "expressiveCode.copyButtonTooltip": "Copy to clipboard",
      "expressiveCode.terminalWindowFallbackTitle": "Terminal window"
      }

      Starlight 的搜索模态框由 Pagefind 库提供支持。 你可以在同一个 JSON 文件中使用 pagefind 键来设置它的 UI 字符串翻译。

      {
      "pagefind.clear_search": "Clear",
      "pagefind.load_more": "Load more results",
      "pagefind.search_label": "Search this site",
      "pagefind.filters_label": "Filters",
      "pagefind.zero_results": "No results for [SEARCH_TERM]",
      "pagefind.many_results": "[COUNT] results for [SEARCH_TERM]",
      "pagefind.one_result": "[COUNT] result for [SEARCH_TERM]",
      "pagefind.alt_search": "No results for [SEARCH_TERM]. Showing results for [DIFFERENT_TERM] instead",
      "pagefind.search_suggestion": "No results for [SEARCH_TERM]. Try one of the following searches:",
      "pagefind.searching": "Searching for [SEARCH_TERM]..."
      }

    通过在 i18nSchema() 选项中设置 extend 可以向你网站的翻译字典中添加自定义键。 在下面的示例中添加了一个新的可选的 custom.label 键:

    src/content.config.ts
    import { defineCollection, z } from 'astro:content';
    import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders';
    import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';
    export const collections = {
    docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
    i18n: defineCollection({
    loader: i18nLoader(),
    schema: i18nSchema({
    extend: z.object({
    'custom.label': z.string().optional(),
    }),
    }),
    }),
    };

    在 Astro 文档的“定义集合模式”中了解有关内容集合 schema 的更多信息。

    你可以使用由 i18next 提供支持的统一 API 访问 Starlight 的 内置 UI 字符串 以及 用户定义插件提供 的 UI 字符串。 其中包括了对 插值多元化 等功能的支持。

    在 Astro 组件中,此 API 作为 全局 Astro 对象 的一部分提供,即 Astro.locals.t

    example.astro
    <p dir={Astro.locals.t.dir()}>
    {Astro.locals.t('404.text')}
    </p>

    你还可以在 端点 中使用 API,其中的 locals 对象可作为 端点上下文 的一部分使用:

    src/pages/404.ts
    export const GET = (context) => {
    return new Response(context.locals.t('404.text'));
    };

    在 Starlight 插件的上下文中,你可以使用 useTranslations() 助手函数来访问特定语言的此 API。 有关更多信息,请参阅 插件参考

    使用 locals.t() 函数以渲染 UI 字符串。 这是 i18next 的 t() 函数的一个实例,该函数将 UI 字符串键作为其第一个参数,并返回当前语言的相应翻译。

    例如,给定一个包含以下内容的自定义翻译文件:

    src/content/i18n/en.json
    {
    "link.astro": "Astro documentation",
    "link.astro.custom": "Astro documentation for {{feature}}"
    }

    第一个 UI 字符串可以通过将 'link.astro' 传递给 t() 函数来渲染:

    src/components/Example.astro
    <a href="https://docs.astro.build/">
    {Astro.locals.t('link.astro')}
    </a>
    <!-- 渲染结果:<a href="...">Astro documentation</a> -->

    第二个 UI 字符串对 {{feature}} 占位符使用了 i18next 的 插值语法feature 的值在被作为第二个参数传递给 t() 时,必须被设置在一个选项对象中:

    src/components/Example.astro
    <a href="https://docs.astro.build/en/guides/astro-db/">
    {Astro.locals.t('link.astro.custom', { feature: 'Astro DB' })}
    </a>
    <!-- 渲染结果:<a href="...">Astro documentation for Astro DB</a> -->

    有关如何使用 t() 函数进行插值、格式化等更多信息,请参阅 i18next 文档

    locals.t.all() 函数可返回一个对象,返回的对象中包含当前区域设置下所有可用的 UI 字符串。

    src/components/Example.astro
    ---
    const allStrings = Astro.locals.t.all();
    // ^
    // {
    // "skipLink.label": "Skip to content",
    // "search.label": "Search",
    // …
    // }
    ---

    要检查某个区域设置是否存在某个翻译键,请使用 locals.t.exists() 函数,并将该翻译键作为第一个参数。 如需覆盖当前的区域设置,请传递第二个可选参数。

    src/components/Example.astro
    ---
    const keyExistsInCurrentLocale = Astro.locals.t.exists('a.key');
    // ^ true
    const keyExistsInFrench = Astro.locals.t.exists('another.key', { lng: 'fr' });
    // ^ false
    ---

    有关详细信息,请参阅 i18next 文档中的 exists() 参考

    locals.t.dir() 函数可返回当前或特定语言环境的文本方向。

    src/components/Example.astro
    ---
    const currentDirection = Astro.locals.t.dir();
    // ^
    // 'ltr'
    const arabicDirection = Astro.locals.t.dir('ar');
    // ^
    // 'rtl'
    ---

    有关详细信息,请参阅 i18next 文档中的 dir() 参考

    你可以使用 Astro.currentLocale.astro 组件中读取当前的语言环境。

    下面的示例读取当前语言环境,并使用它和 getRelativeLocaleUrl() 助手函数以生成一个当前语言的关于页面的链接:

    src/components/AboutLink.astro
    ---
    import { getRelativeLocaleUrl } from 'astro:i18n';
    ---
    <a href={getRelativeLocaleUrl(Astro.currentLocale ?? 'en', 'about')}>About</a>