在 Next.js 开发国际化(i18n)项目时,许多人会直接安装 next-intl、react-intl、i18next 这样的重量级库。 但对于一些结构简单、只需要基础文本翻译的网站来说,使用这些库反而会带来额外的复杂性。
如果你只想让项目支持:
✔ 标题多语言 ✔ 按钮多语言 ✔ 文案多语言 ✔ 扩展灵活、无需复杂配置
那么你完全可以自己写一个 超轻量 i18n 方案。
今天我们来介绍一个非常简单、方便扩展、可在任何环境使用的多语言实现方式: 基于 JSON 语言包 + t() 翻译函数。
目录结构:简单、清晰、可扩展
首先在项目中新建 i18n 文件夹:
bash
/i18n
├─ en.json
├─ de.json
├─ fr.json
内容例如:
en.json
json
{
"hotTags": "Hot Tags",
"hotArticles": "Hot Articles",
"latestNews": "Latest News"
}
de.json
json
{
"hotTags": "Beliebte Tags",
"hotArticles": "Beliebte Artikel",
"latestNews": "Neueste Nachrichten"
}
fr.json
json
{
"hotTags": "Tags Populaires",
"hotArticles": "Articles Populaires",
"latestNews": "Dernières Nouvelles"
}
自定义 t() 翻译函数
这一小段代码就是整个多语言系统的核心:
ts
import en from "@/i18n/en.json";
import de from "@/i18n/de.json";
import fr from "@/i18n/fr.json";
const locales = { en, de, fr };
export function t(locale: string, key: string): string {
const dict =
(locales as Record<string, Record<string, string>>)[locale] || locales["en"];
return dict[key] ?? key;
}
工作原理
- 根据传入的 locale(
en/de/fr)选择对应字典 - 如果找不到语言,自动使用英文作为 fallback
- 如果 key 不存在,原样返回 key(方便调试)
类型安全(解决 TS 报错)
上面代码使用了:
ts
(locales as Record<string, Record<string, string>>)
让 TypeScript 明确知道字典是:
- key: 语言代码
- value: 文本映射表(键值对)
这样就不会出现:
「元素隐式具有 any 类型」
在页面中使用
示例: 你在首页 HomePage 中传入 locale:
tsx
<h2 className="text-2xl font-bold">
{t(locale, "hotTags")}
</h2>
渲染效果将根据语言不同自动变化:
- English → Hot Tags
- Deutsch → Beliebte Tags
- Français → Tags Populaires
无需额外库,无需复杂配置。
优点总结
| 特点 | 说明 |
|---|---|
| 极轻量 | 无需安装任何 i18n 库 |
| 纯 JSON 文件 | 非技术人员也能直接编辑 |
| 完全可控 | 不会被第三方库的 API 或复杂行为束缚 |
| 易扩展 | 想加语言?加个 JSON 文件即可 |
| 易维护 | 键值结构简单不容易出错 |
适合用在:
- 企业官网
- 展示性网站
- CMS 文章网站(如 Strapi + Next.js)
- SEO 友好的多语言站点
- 需要快速上线 MVP 的项目
还能进一步增强!
要是你想扩展成更强的国际化系统,你还可以加入:
✔ 支持嵌套 key(如 home.title)
✔ 支持变量插值(如 Hello {{name}})
✔ 自动检测浏览器语言
✔ 服务端自动注入 locale(Next.js App Router)
我可以进一步为你升级成 完整简易版 i18n 框架。
最后
这种方式简单却非常实用,特别适合 已经有后端(例如 Strapi) + 前端 Next.js 结构的多语言站点。