高级用法 /

为不同域名配置不同默认语言

Creght 支持为同一个网站绑定多个域名,并让不同域名使用不同的默认语言。这个能力适合多国家、多地区网站:同一套网站内容和 CMS 数据,可以在不同市场使用更自然的访问路径。

例如,example.com/about 可以显示英文,example.fr/about 可以显示法文,而且不需要访问 example.fr/fr/about

前提条件

  • 网站已经开启多语言。
  • 相关域名已经绑定到同一个网站。
  • 每个语言都已经加入 locales 配置。

注意:i18n.domains 只负责语言路由。域名本身仍然必须先在「设置 → 域名」中绑定到当前网站,否则请求不会进入这个网站的语言配置。

配置示例

talizen.config.ts 中添加 i18n.domains

export default {
  i18n: {
    defaultLocale: "en",
    locales: ["en", "fr"],
    localeDetection: true,
    domains: [
      { domain: "example.com", defaultLocale: "en" },
      { domain: "example.fr", defaultLocale: "fr" },
    ],
  },
}

配置后:

  • example.com/about 使用英文。
  • example.fr/about 使用法文。
  • /fr/about 仍然可以作为显式语言路径使用。
  • 如果语言检测或显式语言前缀命中另一个域名承载的语言,系统会跳转到对应域名。

字段说明

defaultLocale 是网站的基础默认语言,通常也是 CMS 基础字段使用的语言。

locales 是网站支持的全部语言列表。

domains 用来声明不同域名对应的默认语言。每一项中的 domain 是要匹配的域名,defaultLocale 是这个域名在无语言前缀路径下使用的语言。每一项还可以写 locales,声明该域名除默认语言外还承载哪些语言(见下一节)。

domains 里的 locales:让一个域名承载多种语言

默认情况下,每个域名只服务它自己的 defaultLocale(无前缀访问)。domains[].locales 用来声明这个域名额外再承载哪些语言——这些语言在本域名下通过带前缀的路径访问,而不会被跳转到其他域名。

不写 locales 会怎样?

不写 locales 不会报错,但域名会退化成单语言:只认自己的 defaultLocale。此时用户在这个域名上访问其他语言(带语言前缀,或自动检测命中),会被 307 跳转到「拥有」那门语言的域名(按各域名的 defaultLocale 匹配)。如果没有任何域名拥有该语言,则退回在当前域名用带前缀的路径提供,不跳转。

用一个中英双语站点举例,站点基础默认语言是中文:

export default {
  i18n: {
    defaultLocale: "zh-CN",
    locales: ["zh-CN", "en"],
    domains: [
      { domain: "www.example.cn", defaultLocale: "zh-CN", locales: ["zh-CN", "en"] },
      { domain: "www.example.com", defaultLocale: "en" },
    ],
  },
}

访问结果:

www.example.cn/about        → 中文(无前缀默认)
www.example.cn/en/about     → 英文(.cn 也承载 en,正常显示,不跳转)
www.example.com/about       → 英文(无前缀默认)

如果把 .cnlocales 去掉,.cn 就只剩中文:再访问 www.example.cn/en/about 会被 307 跳转到 www.example.com/about——英文被「甩」到了 .com。所以要让一个域名同时提供多种语言,必须在它的 locales 里把这些语言列全(把它自己的 defaultLocale 也一并写上会更清晰)。

一句话:locales 是「把这个域名变成多语言」的开关。一个域名只服务一门语言时可以省略;需要双语/多语时必须写。这与 Next.js 的 i18n.domains[].locales 语义一致——表示「除 defaultLocale 外还应路由到该域名的其他语言」。

多语言路径规则

没有配置多域名时,Creght 默认使用路径前缀区分语言:

/about     → 默认语言
/fr/about  → 法文
/zh/about  → 中文

配置多域名后,每个域名可以拥有自己的无前缀默认语言:

example.com/about  → 英文
example.fr/about   → 法文

这样用户访问地区域名时,不需要再看到额外的语言前缀。

常见问题

为什么 example.fr 不需要 /fr?

因为 example.fr 已经在 i18n.domains 中声明了默认语言:

{ domain: "example.fr", defaultLocale: "fr" }

所以 example.fr/about 的无前缀路径会直接按法文处理。

只写 i18n.domains 就可以了吗?

不可以。域名还必须绑定到同一个网站。如果 example.fr 没有在「设置 → 域名」中绑定到当前网站,平台无法把这个请求解析到当前网站,自然也不会读取当前网站的 i18n.domains 配置。

可以一个域名支持多个语言吗?

可以。域名的 defaultLocale 是无前缀默认语言,其他语言仍然可以通过路径前缀访问。

export default {
  i18n: {
    defaultLocale: "en",
    locales: ["en", "nl-NL", "nl-BE"],
    domains: [
      {
        domain: "example.nl",
        defaultLocale: "nl-NL",
        locales: ["nl-BE"],
      },
    ],
  },
}

访问结果:

example.nl/about        → nl-NL
example.nl/nl-BE/about  → nl-BE

为什么用 localizedPath / <Link> 生成的链接没有语言前缀?

这是正确行为。多域名下,<Link>localizedPath() 以「当前域名的无前缀默认语言」为准:当目标语言正好是当前域名的默认语言时,链接不带前缀。例如在 www.example.com(默认 en)上,localizedPath("/about", "en") 返回 /about 而不是 /en/about;只有切到该域名的非默认语言时才会带前缀。这也是不建议手动拼接语言路径的原因。

推荐做法

为每个主要市场配置独立域名,例如:

example.com  → en
example.fr   → fr
example.de   → de

站内链接请使用 Creght/Talizen 的多语言链接能力,例如 <Link>localizedPath(),不要手动拼接语言路径。这样在未来调整默认语言或域名策略时,链接更容易保持正确。

Render diagnostics