1534 字
8 分钟
全方位多语言国际化
2026-06-15
无标签

全方位多语言 (i18n)#

走向世界,从支持国际化开始。本框架对 i18n 做了深度解耦和极其完善的安全防护。

防串台隐身机制#

当你在主语言下发布了一篇博文,但尚未将其翻译至英语环境时,这篇博文在英语环境的首页、分类页、标签流中将彻底隐身。这种“宁缺毋滥”的策略保证了外语用户绝对不会在他们的信息流中看到夹杂的其他语言文章。

只有当你在对应的语言文件夹(例如 src/content/blog/en/)下创建了完全同名(相同 slug)的翻译版文件后,它才会在英语信息流中浮出水面。

孤岛访问保护与红黄降级#

虽然信息流中隐身了,但如果有人在浏览器地址栏手动输入了不存在的外语版链接,或者通过分享链接强行切换语言,会发生什么?

系统不会报 404 错误!相反,系统会智能地抓取主语言的文章进行展示,并在标题上方打上鲜艳的红黄色语言警告提示框

这个提示框会温和地提醒访客:

“The requested language is not available. Showing the default language version.”

同时,提示框内会高亮列出该文章真正支持的语言标签(且标签会根据亮暗模式智能切换文字颜色 text-white / text-black),引导访客点击切换到正确的阅读环境,避免陷入阅读死角。

主语言系统与路由魔法#

在 Fuwari 中,有一个非常重要的概念叫 主语言 (Main Language)

什么是主语言?如何设置?#

主语言代表了你这个网站最核心、最默认的面向受众群体的语言。 你可以在 src/config.ts 中通过修改 siteConfig 轻松设置主语言,同时通过 languages 数组开启你想要支持的其它语言:

export const siteConfig: SiteConfig = {
// ...
lang: "zh_CN", // 将中文设为主语言
languages: ["en", "ja", "ko"], // 声明支持的其它语言
// ...
}

主语言与其他语言的区别#

  1. 内容降级兜底:当你在其它语言环境中访问了未翻译的组件、未翻译的文章、或者未翻译的自定义 Tag 时,系统会默认退回到主语言抓取对应内容进行兜底展示(Fallback 策略)。
  2. 路由前缀自动消隐:这是主语言系统的一大魔法!对于主语言来说,它的路由会自动去掉语言路径。
    • 比如你将主语言设置为 zh_CN,你在访问中文“关于”页面时,网址会干净利落地显示为:https://你的域名/about/
    • 而当你切换到其它外语(如英语 en 或日语 ja)时,它们的网址则会规范地带上前缀:https://你的域名/en/about/https://你的域名/ja/about/。 这种设计既保持了主页面 URL 的优雅与简短,又对搜索引擎 (SEO) 极其友好。

主语言内容的专属文件夹(可选)#

在存放 Markdown 文件时,你可以直接将主语言的文章放在根目录(例如 src/content/blog/xxx.md)。但如果你是个强迫症,希望所有语言的文件都能隔离存放,系统同样支持为主语言创建独立的语言文件夹

  • 比如,在主语言为 zh_CN 的情况下,src/content/blog/zh_CN/xxx.md 与直接放在根目录的 src/content/blog/xxx.md完全等价的,它们最终都会被渲染到主语言的无前缀路由下。
  • 注意防冲突:既然两者等价,请千万不要在根目录和 zh_CN 目录下同时创建两个同名(Slug 相同)的文章!如果发生这种路径冲突,系统为了防止内容覆盖,会在编译阶段直接报错。

标签与字典:如何补充 i18n Tag?#

除了文章内容,网站中还有大量的固定文字、按钮提示以及友链标签(Tag)需要被翻译。

1. 注册新的 I18n Key#

当你需要新增一个可以被翻译的词条时(例如在深层定制中加入了一个叫 tag.schoolmate 的新 Tag),你需要先在 src/i18n/i18nKey.ts 中注册它:

enum I18nKey {
// ...
tagSchoolmate = 'tag.schoolmate', // 注册新键值
}
WARNING

全站通用 Key 绝对不允许以中括号 [...] 开头(例如 [my-widget]title)。这是因为系统底层通过中括号来精确识别和隔离特定组件的专属翻译。如果你强行在全局 Key 中使用该格式,系统会在编译合并时主动报错拦截。若你对这种将特定组件的翻译“物理隔离”的机制感兴趣,请查阅更高级的 分块模块化 i18n 配置指南

2. 在语言字典中补充翻译#

注册完毕后,进入 src/i18n/languages/ 目录,分别在对应的语言文件中补充翻译。 最重要的是:你必须在你的主语言文件(例如 zh_CN.ts)中补充它!

import I18nKey from "../i18nKey";
import type { Translation } from "../translation";
export const zh_CN: Translation = {
// ...
[I18nKey.tagSchoolmate]: "同学",
};

只要主语言配置了翻译,即便你忘记在 en.tsja.ts 中编写对应的翻译,系统也只会降级显示主语言的词条,绝不会造成页面崩溃。

如何新建语言支持?#

得益于我们在底层引入的完全自动化构建机制,现在如果你想支持系统默认未配置的全新语言(例如德语 de),仅需极其简单的两步

  1. 字典创建:在 src/i18n/languages/ 目录下新建 de.ts,照猫画虎将 zh_CN.ts 里的所有字段用德文翻译一遍并导出。
  2. 启用语言:打开 src/config.ts,在 languages 数组中加上 "de" 即可大功告成!

这就是全部! 系统会在编译阶段自动拦截你的 de.ts 并完成字典注册;同时路由底层也会自动为你生成所有相关的页面重定向与外链访问保护白名单!现代前端框架的优雅,就体现在这种极致的开发者体验上。

全方位多语言国际化
https://aquamarine-z.github.io/docs/fuwari/05-i18n-guide/
作者
Aquamarine
发布于
2026-06-15
许可协议
CC BY-NC-SA 4.0