前言
网站做多语言,不论是从 SEO 的角度上来说,还是用户体验上,都是具有非常可观的效益的。 有些时候,不正确的多语言实现,可能会拖慢整个网站的体验,甚至会降低 LCP/FCP 等指标,影响 SEO 排名。
从0到1来实现多语言,我认为大多数情况下解决下面这三个问题即可:
- 如何迁移到多语言?
- 如何管理、翻译和校对键值对?
- 如何使用SSR确保网页性能?
如何迁移到多语言
就前端来说,大多数的产品,并不会一开始就将多语言纳入到产品开发中,而是随着迭代作为需求更新。
这时的产品,往往会有着硬编码文本和没有适配多语言的路由。那么如何迁移主要也就是
提取所有文本,并且改造路由,至于写 proxy.ts 之类的,因项目而异,这里不过多赘述了。
如果你的页面不多,手动提取文本,把他们改造成 t('key') 的形式是可行的,如果有着大量的页面和文本,如果还在手动迁移
,那简直就是一场枯燥无味、繁琐重复的灾难。
如果你的 token 多得用不完,你可能会想说,为何不试试让 Agent 去逐页迁移呢?当然可以,不过我认为更效率的方法可能是去写个正则、写个脚本来提取文本到一个 csv/json 文件中,然后再去做翻译和校对,虽然你的 Agent 也会建议你这样做。
当然你也可以选用一些广泛使用的工具,比如说 i18next-cli,虽然需要一些配置,但通常来说会更轻松一点,因为不需要自己去维护。
另一个问题是改造路由,不是所有的页面都需要 i18n,什么页面不需要呢,可以通过对 SEO 的影响来判断,如果你不希望这个页面被搜索引擎收录,那么很大程度上,这个页面
就不需要 i18n 了,除非这个页面真的能够影响用户的体验。一旦你确定了哪些页面需要做 i18n,你就可以正式开始改造路由了,比较广泛的使用的做法是加一个前缀,可能是
这样的 web.site/[locale]/[page],在项目仓库中,需要使用 git mv 去移动文件以保全代码的变动历史,避免不必要的冲突。
在你做完这些后,那就需要开始考虑 SEO 了,你需要修改页面的 meta 标签,添加 hreflang,并且在 sitemap.xml 中添加多语言的路由。这样来说,前端的前期工作就算是完成了。
对了,如果你有些文本存在了后端或是数据库中,不要忘记把他们也一并迁移到多语言中去,这种情况下就会稍有些复杂,不过实际上没有太多阻碍的地方,这里就不过多赘述了。
如何管理、翻译和校对键值对
通常来说有两种方法:CMS(即 Content Management System - 内容管理系统) 和 Git。
CMS 是比较规范的做法,开发人员和翻译人员可以互不干扰,翻译人员可以在 CMS 中直接进行翻译和校对,而开发人员只需要在项目中使用 t('key') 即可。CMS 的好处是可以让翻译人员专注于翻译和校对,而不需要关心代码的实现细节,从而实现开发人员和翻译人员的解耦。想象一下,把 messages/ 添加到 .gitignore 中,然后在 CMS 中进行翻译和校对,最后再通过 CI/CD 的方式将翻译好的文件同步到项目中,听着是不是非常好?
你可以自建 CMS,只要你有办法能够拉取和推送翻译文件到项目中即可,或者你也可以使用一些 CMS 服务,比如说 Crowdin。
另一种方法就是使用 Git 来随代码一同管理了,低成本并且便于调试,这是最朴素的方法,但是也有一些缺点,比如说翻译人员需要了解 Git 的使用,或者需要开发人员来协助翻译人员进行翻译和校对,这样就会增加开发人员的工作量。
为何不试试直接让开发人员去做翻译呢,哈哈
在你能够管理好键值对后,那么翻译和校对也会很简单了,无论是在 CMS 中,还是用 Git 来管理,翻译和校对实际上就是把源文本和 对应的翻译文本进行比对,那么实际上就只需要提取源文本和对应的翻译文本就行了,如果用 CMS,整件事会更简单一些。
如何使用 SSR 确保网页性能
为什么做完 i18n 后,网站变得非常卡。那么很可能是 SSR 出问题了。
如果要理解 SSR,那么就需要先具备能够区分 Server Components 和 Client Components 的能力,Server Components 是在服务端渲染的组件,而 Client Components 是主要在客户端渲染的组件。如果在客户端渲染的组件中使用了 t('key'),那么就会出现一个问题,直到客户端拉取键值对渲染(也就是 CSR),才会对键值对进行拉取进而渲染,与完全在服务端渲染相比,多出了一个客户端拉取渲染的过程,这就会导致 FCP/LCP 等指标变差。最后网站可能会变得很卡,用户体验很差。
我认为这个问题是一个另类的红蓝函数问题,把组件看作是一棵树,所有客户端组件会导致底下的服务端组件包括其子树无法充分利用服务端渲染,把更多本应在服务端完成的工作推到客户端完成,如果你需要交互,并且性能达到最优,那么你就需要把整个树撕碎,让所有有交互的客户端组件尽可能靠近边缘,这也就是前端所说的组件拆分的意义,这样能够充分利用 SSR 的优势,减少不必要的渲染和数据拉取。
如何使用 SSR 确保网页性能呢?实际上就是组件拆分和服务端/客户端组件的重新划分。
