国际化指南

Astro Plain 的国际化(i18n)指南:翻译函数用法、配置规范与新增语言步骤。

阅读时间: 5分钟
作者:

特性概览

  • 智能重定向:根据 Cookie 或浏览器首选语言自动跳转至对应语言首页。
  • 无感上下文注入:基于 ts-intl-astro,组件内无需手动透传 lang 参数,直接调用 useTranslations 或 useLocale。
  • 多语言文章关联:无需嵌套子目录,通过 Frontmatter 的 translationKey 自动关联各语言版本并生成对应 SEO 规范标签(canonical / hreflang)。

文件结构

  • 目录i18n/
    • index.ts 国际化核心初始化与方法导出
    • 目录messages/ 各语言翻译字典
      • zh-Hans.ts 中文字典
      • en-US.ts 英文字典
      • ja-JP.ts 日文字典
  • 目录src/content/
    • 目录blog/ 博客文章(通过 translationKey 关联)
      • …
    • 目录author/ 作者信息(按语言分目录)
      • …
    • 目录project/ 项目介绍(按语言分目录)
      • …
    • 目录mdx/ 其他 MDX 内容(按语言分目录)
      • 目录[lang]/
        • hero.mdx 首屏区域(Hero Section)
  • astro.config.mjs 集成配置(注册 tsIntl())
  • site.config.ts 站点核心参数配置

翻译函数用法

本项目国际化基于 ts-intl-astro (在新窗口打开) 实现,在 Astro 组件树中自动注入当前语言上下文。

基础用法(绑定命名空间)

推荐在组件中绑定所需的命名空间,调用 t 时直接传入词条键名:

src/components/Header.astro
---
import { useTranslations } from "~/i18n";
// 绑定 `common` 命名空间
const t = useTranslations("common");
---
<header>
<h1>{t("header_title")}</h1>
<a href="/">{t("home")}</a>
</header>

全局命名空间访问

若不传入命名空间参数,可通过 namespace.key 访问任意命名空间下的词条:

---
import { useTranslations } from "~/i18n";
const t = useTranslations();
---
<p>{t("common.home")}</p>
<p>{t("search.placeholder")}</p>

获取当前语言代码

在需要拼接本地化路由或传递给外部组件时,使用 useLocale() 获取当前页面的语言代码:

---
import { useLocale } from "~/i18n";
const lang = useLocale();
---
<a href={`/${lang}/about`}>关于</a>

参数插值

词条中支持使用 {param} 占位符,调用时通过对象传入变量值:

---
import { useTranslations } from "~/i18n";
const t = useTranslations("common");
// 字典定义:link_to: "链接到{title}"
---
<p>{t("link_to", { title: "Astro" })}</p>
{/* 输出:链接到 Astro */}

非组件环境调用

在 API 路由(如 rss.xml.ts)或静态路径生成(getStaticPaths)等无 Astro 渲染上下文的环境中,使用 getTranslations 显式传入语言代码:

import { getTranslations } from "~/i18n";
const t = getTranslations("zh-Hans", "common");
const siteTitle = t("site_title");

新增语言

为站点添加一门新语言(例如法语 fr-FR),只需以下 4 步:

  1. 在站点配置中添加语言映射

    在 site.config.ts 的 languageNameMap 中加入新语言代码与显示名称:

    site.config.ts
    const SiteConfig = {
    // ...
    languageNameMap: {
    "en-US": "English",
    "ja-JP": "日本語",
    "zh-Hans": "简体中文",
    "fr-FR": "Français",
    },
    };
  2. 创建翻译字典文件

    在 i18n/messages/ 目录下新建 fr-FR.ts。建议参考现有字典补全词条:

    i18n/messages/fr-FR.ts
    const frFR = {
    common: {
    home: "Accueil",
    about: "À propos",
    link_to: "Lien vers {title}",
    page_num: "Page {num}",
    // ... 其他词条
    },
    } as const;
    export default frFR;
  3. 注册新字典

    在 i18n/index.ts 中导入并注册到 createAstroI18n:

    i18n/index.ts
    import zhHans from "./messages/zh-Hans";
    import enUS from "./messages/en-US";
    import jaJP from "./messages/ja-JP";
    import frFR from "./messages/fr-FR";
    export const {
    useTranslations,
    useLocale,
    useFormatter,
    getTranslations,
    // ...
    } = createAstroI18n({
    defaultLanguage: "zh-Hans",
    messages: {
    "zh-Hans": zhHans,
    "en-US": enUS,
    "ja-JP": jaJP,
    "fr-FR": frFR,
    },
    });
  4. 添加对应的作者信息与首屏内容

    在 src/content/author/ 与 src/content/mdx/ 下创建新语言目录及文件:

    • src/content/author/fr-FR/default.mdx
    • src/content/mdx/fr-FR/hero.mdx

撰写多语言文章

多语言文章均存放在 src/content/blog/ 下,无需按语言分文件夹。系统依据 Frontmatter 的 translationKey 自动关联不同语言版本:

---
title: "Astro Plain 介绍"
summary: "博客模板介绍"
translationKey: "my-first-post"
language: "zh-Hans"
date: "2026-09-01T12:00:00Z"
isCanonical: true
---
文章中文内容...

NOTE

  • translationKey:同一文章的不同语言版本需保持该值完全一致。
  • isCanonical:建议在默认语言(如中文版)中设置为 true,以供生成多语言权威链接(canonical 与 x-default)。
最后修改于: