国际化

本站支持三种语言,提供完整的内容与界面翻译。

支持的语言

代码

标签

角色

en

English

默认语言

zh-CN

简体中文

简体中文

ja

日本語

日语

配置位于 src/lib/i18n.ts

export const locales = ["en", "zh-CN", "ja"] as const;
export type Locale = (typeof locales)[number];
export const defaultLocale: Locale = "en";

语言路由

所有路由均以语言段作为前缀(例如 /en/blog/zh-CN/blog)。src/middleware.ts 中的中间件负责执行此规则:

  1. 直通 --- 对 /_next/api/fonts 以及静态文件(路径中包含 .)的请求不做处理

  2. 有效语言 --- 如果路径的第一段是 enzh-CNja,请求将直接通过,不做修改

  3. 检测 --- 解析 Accept-Language 请求头;选择第一个匹配的语言,若无匹配则回退到 en

  4. 重定向 --- 将用户重定向到 /{detectedLocale}{path}

中间件匹配器排除了 _nextapifontsfavicon.icorobots.txtsitemap.xml

翻译系统

t() 函数提供带占位符支持的界面翻译:

t(key: string, locale: Locale, params?: Record<string, string | number>): string

行为:

  • 返回给定语言对应的翻译字符串

  • 如果请求的语言中缺少该键,则回退到 en

  • 如果完全不存在翻译,则返回原始键名

  • 支持 {placeholder} 插值:t("pageOf", "zh-CN", { page: 1, total: 5 })"第 1 页,共 5 页"

翻译键

共定义了约 80 个键,按功能区域组织:

Navbar: brand, blog, gallery, solutions, pricing, developer, login, adminLogin

博客: readMorefeaturedArticlesallArticlesnoArticlesnoArticlesTitlenoArticlesDescpublishedOnbyfilterByCategoryfilterByTag``(含 ``{tag})、allCategoriessearchPlaceholdercategoriestagssharecopyLinklinkCopiedseeMorehomelastUpdated``(含 ``{date}

图库: mediaGallerynoGalleriesviewGalleryphotos

分页: previousnextpageOf``(含 ``{page}{total}

页脚: 分区标题(productsplatformservicescompany)、链接标签、法律链接(termsOfServicedisclaimerprivacyPolicymanageCookies)、copyright``(含 ``{year})、icp

Cookie 同意: 横幅文本和按钮、设置对话框标题和开关说明(必要、性能、广告)

主题: lightModedarkMode

错误: backToHomehttpErrorCodeerrorSuggesttryAgain,以及 HTTP 状态码 400、401、403、404、405、408、429、500、502、503、504 和默认错误的标题与描述

SEO: siteTitlesiteDescription

CMS 内容本地化

Strapi 文章和分类在服务端进行本地化。种子脚本首先创建英文内容,然后通过 Strapi 的 /actions/localize 端点添加 zh-CN 和 ja 的本地化版本。

fetchPublicArticlesfetchCategories 函数会将 locale 查询参数传递给 Strapi,Strapi 据此返回相应的翻译内容。

添加新语言

  1. src/lib/i18n.tslocales 数组中 添加语言代码

  2. localeLabels添加标签(例如 "ko": "한국어"

  3. 在翻译对象中为所有键 添加翻译

  4. 在 Strapi 中为已有文章和分类 添加 CMS 本地化内容

  5. 测试 中间件能否从 Accept-Language 检测到新语言

LocaleSwitcher 组件会自动渲染 localeLabels 中的所有条目,因此无需修改组件代码。