← 返回题目列表

SSR 项目中的国际化和多语言页面如何设计?

中等 第 24 / 25 题 更新于 2026/07/29
SSR国际化i18nSEO

简化版

SSR 国际化要解决语言识别、翻译资源加载、URL 结构、SEO 标签和缓存隔离。常见做法是用路径区分语言,例如 /zh//en/,服务端根据 URL 加载对应语言包并渲染 HTML,同时输出 langhreflang、canonical 等标签。不要只在客户端切语言,否则首屏 HTML、SEO 和缓存都容易出问题。

详细版

多语言 SSR 页面最怕“服务端一套语言,客户端水合后变另一套语言”。这会造成闪烁、水合不一致,也会让搜索引擎拿到错误内容。

规范设计里,语言应该是路由、请求上下文和缓存 key 的一部分。翻译资源可以按语言分包加载,日期、货币、数字格式也要跟 locale 统一。

面试时要强调:国际化不只是文本替换,还包括 URL、SEO、格式化、缓存和兜底策略。

完整版教学

一、语言从哪里来

可以从 URL 路径判断,例如 /en/products

可以从子域名判断,例如 en.example.com

可以从用户设置或 Cookie 判断。

也可以参考 Accept-Language,但它更适合作为首次访问的辅助判断。

对 SEO 页面来说,路径或域名通常比纯 Cookie 更稳定。

二、推荐 URL 结构

方案示例特点
路径前缀/zh/about实现直观,SEO 友好
子域名en.example.com品牌区隔清晰,运维稍复杂
参数/about?lang=en简单但 SEO 表达较弱
Cookie无固定 URL个性化方便,不适合公开索引页

三、SSR 渲染流程

解析 URL 得到 locale。

加载对应语言包。

获取页面数据。

用 locale 格式化日期、金额、数字。

输出 HTML、html lang、SEO 标签和 hydration 初始状态。

多语言页面要让服务端 HTML 就是目标语言,而不是等客户端再替换。

四、代码示例

export async function renderI18nPage(request: Request) {
  const locale = getLocaleFromUrl(new URL(request.url).pathname);
  const messages = await loadMessages(locale);

  return renderHtml({
    locale,
    messages,
    title: messages["home.title"],
  });
}

客户端水合时要复用同一个 locale 和 messages,避免重新判断出不同语言。

五、SEO 细节

html lang 要准确。

不同语言页面应有稳定 URL。

可以使用 hreflang 告诉搜索引擎语言版本关系。

canonical 要指向当前语言的规范 URL,避免错误合并。

站点地图也应包含多语言 URL。

六、缓存设计

如果 HTML 按语言不同,CDN 缓存 key 必须包含语言维度。

路径前缀天然能隔离缓存。

如果用 Cookie 或请求头判断语言,要谨慎设置 Vary

否则用户可能拿到别人语言的 HTML。

七、误区和追问

  • 误区:国际化就是把中文替换成英文。 还包括 URL、SEO、格式化、排序、兜底和缓存。
  • 误区:用浏览器语言自动跳转一定最好。 自动跳转可能干扰搜索引擎和用户主动选择。
  • 误区:客户端切语言就能满足 SSR。 客户端切换太晚,首屏 HTML 和 SEO 已经生成。
  • 追问:语言包很大怎么办? 按 locale 和页面拆包,服务端只加载当前页面需要的资源。
  • 追问:缺少翻译怎么兜底? 可以回退默认语言,但要记录监控,避免长期隐藏问题。
  • 追问:多语言页面怎么防止水合不一致? 服务端和客户端使用同一 locale、同一初始语言包和同一格式化规则。

八、面试收束

回答 SSR 国际化时,不要停在文案替换。

能讲到 URL、SEO、缓存和 hydration,一般就能体现项目经验。