TanStarter Docs

国际化

学习如何在 TanStarter 模板中配置国际化、添加翻译文案和维护本地化内容

TanStarter 已内置基于 Paraglide JS 的国际化能力。默认语言是英文,中文通过 URL 前缀访问:

  • 英文页面:/about
  • 中文页面:/zh/about

涉及文件

国际化功能主要涉及以下文件:

settings.json
en.json
zh.json
middleware.ts
locale.ts
locale-switcher.tsx
文件用途
project.inlang/settings.json配置基础语言和支持的语言列表
project.inlang/messages/en.json英文文案
project.inlang/messages/zh.json中文文案
src/lib/locale.ts导出语言配置、URL 工具和常用消息解析工具
src/locale/middleware.ts接入 Paraglide 中间件,让服务端请求识别当前语言
src/locale/paraglide/Paraglide 生成的运行时代码,不需要手动编辑
src/components/layout/locale-switcher.tsx导航栏和菜单里的语言切换逻辑

不要手动修改 src/locale/paraglide/ 下的文件。它们由 Paraglide 根据 project.inlang/messages/*.json 自动生成。

添加 UI 文案

短文本、按钮、表单标签、错误提示、邮件标题等 UI 文案统一维护在 project.inlang/messages/*.json 中。

1. 添加消息 key

同时在英文和中文文件中添加同名 key:

project.inlang/messages/en.json
{
  "settings_profile_title": "Profile",
  "settings_profile_description": "Update your public profile information."
}
project.inlang/messages/zh.json
{
  "settings_profile_title": "个人资料",
  "settings_profile_description": "更新你的公开个人资料信息。"
}

建议使用模块前缀组织 key,例如:

  • auth_login_title
  • pricing_plan_pro_name
  • dashboard_empty_state_title
  • mail_verify_email_subject

这样后续排序、查找和维护会更清晰。

2. 在组件中使用文案

从 Paraglide 生成的 m 对象读取文案:

src/components/settings/profile-card.tsx
import { m } from '@/locale/paraglide/messages';

export function ProfileCard() {
  return (
    <section>
      <h2>{m.settings_profile_title()}</h2>
      <p>{m.settings_profile_description()}</p>
    </section>
  );
}

保存后,pnpm dev 会自动重新编译 Paraglide 运行时代码。新 key 生成后,就可以通过 m.your_key() 调用。

3. 排序并检查 key

添加或修改文案后,建议运行:

pnpm locale:sort
pnpm locale:check
  • pnpm locale:sort:按 key 前缀和名称排序所有语言 JSON
  • pnpm locale:check:检查不同语言文件里的 key 是否一致

如果某个 key 只添加到了 en.json,但忘记添加到 zh.json,检查命令会提示。

添加本地化 Markdown 内容

博客、更新日志、法律页面等长内容使用 Markdown 文件维护。英文使用基础文件名,中文在 .md 前添加 .zh

content/blog/getting-started.md
content/blog/getting-started.zh.md

content/changelog/v1.0.0.md
content/changelog/v1.0.0.zh.md

content/pages/privacy.md
content/pages/privacy.zh.md

例如,为博客文章添加中文版本:

content/blog/my-first-post.md
---
title: My First Post
description: A short introduction to the product.
date: 2026-01-15
category: Tutorial
image: https://example.com/cover.jpg
---

English content...
content/blog/my-first-post.zh.md
---
title: 我的第一篇文章
description: 一篇简短的产品介绍。
date: 2026-01-15
category: 教程
image: https://example.com/cover.jpg
---

中文内容...

TanStarter 会把这两个文件识别为同一个 slug 的不同语言版本:

  • 英文:/blog/my-first-post
  • 中文:/zh/blog/my-first-post

文件名里的 .zh 只用于区分语言,不会出现在最终 URL 中。

添加新的语言

如果要新增语言,例如日语 ja,需要同时更新语言配置和文案文件。

1. 更新 Inlang 配置

project.inlang/settings.json 中添加新语言:

project.inlang/settings.json
{
  "baseLocale": "en",
  "locales": ["en", "zh", "ja"]
}

2. 添加消息文件

复制一份现有语言文件并翻译:

project.inlang/messages/ja.json

新文件需要包含和 en.jsonzh.json 相同的 key。

3. 更新语言列表

src/lib/locale.ts 中为新语言添加名称、旗帜和 hreflang

src/lib/locale.ts
export const localeConfig = {
  en: {
    flag: '🇺🇸',
    name: 'English',
    hreflang: 'en',
  },
  zh: {
    flag: '🇨🇳',
    name: '中文',
    hreflang: 'zh-CN',
  },
  ja: {
    flag: '🇯🇵',
    name: '日本語',
    hreflang: 'ja',
  },
} satisfies Record<Locale, LocaleConfig>;

语言切换器会读取 localeslocaleConfig,自动显示新增语言。

4. 添加内容文件

如果博客、更新日志或法律页面也要支持新语言,按同样规则创建本地化 Markdown:

content/blog/getting-started.ja.md
content/changelog/v1.0.0.ja.md
content/pages/privacy.ja.md

如果你新增的语言不是 enzh,还需要确认 content-collections.ts 里的语言后缀识别规则包含新语言。

常用命令

pnpm dev             # 启动开发服务器,并自动编译国际化运行时代码
pnpm build           # 构建生产版本,也会编译国际化运行时代码

pnpm locale:sort     # 排序消息 key
pnpm locale:check    # 检查不同语言的消息 key 是否一致
pnpm locale:compile  # 手动编译 Paraglide 运行时代码

日常开发中,通常只需要运行 pnpm dev。添加文案后再运行 pnpm locale:sortpnpm locale:check,可以避免翻译 key 漏加。

下一步

最后更新于

本页目录