Sveltekit的国际化问题以及入口问题app.html的注入
写在前面
接近年末,前端框架也开始卷起来了:
- Svelte 5 发布了 ,据说变得更好了,值得一提的是Svelte的语法真的是非常友善,和Vue有异曲同工之妙,另外文件结构上和NextJS15的App Router很像,都以page,layout这样的方式命名
- NextJS 发布了15 ,基于React 19 RC,这个就不说什么了,生态很强大,轮子齐全
- Solidstart 发布了1.0,生态不够,文档非常匮乏,前天把i18n实现了,感觉很繁琐,用着不舒服
整体来说Svelte和Solid的性能会比NextJS好很多,打包出的客户端资源会小很多,因此基于这两者开发出的应用在老旧的设备和不顺畅的网络情况下体验上会更好。
一通折腾下来最后选择了Sveltekit作为下一个比较大的、互动多的项目,以SSR为主的前端框架,而Astro则作为内容为主的SSG静态站点的选择。
进入主题
i8n方案
- sveltekit-i18n 目前我的选择,尽管看上去很复杂,但是有详细的文档
- typesafe-i18n 非常不幸的是,作者在一次跑步比赛中去世了
- Paraglide JS 不好用,未来可能会商业化
在使用sveltekit-i18n的过程中发现的问题:
1.带有特殊字符的语言代码无法正确得到route参数
比如 zh-CN,us-US这样的语言代码它无法正确识别,最后由于不想修改原代码以免影响日后升级我选择了妥协,使用了ISO639语言代码,以中文为例直接用zh,而不是区分zh-CN, zh-TW, zh-Hans之类
问题体现:page返回的data中
正确的是:{route: "/about", lang: "zh-CN"}, {route: "/about", lang: "en"}, {route: "/about", lang: "fr"}
但是它返回了:{route: "/zh-CN/about", lang: "zh-CN"},这导致切换语言的URL错误
2.app.html的lang标签
这是个小问题由于lang中的值是en,而没有替换为字符串 %lang%,我检查了文件hooks.server.js,它写了注入的过程,但是最终没有实现
// Add html `lang` attribute return resolve({ ...event, locals: { lang: locale } }, { transformPageChunk: ({ html }) => html.replace('%lang%', `${locale}`), });
这是app.html注入的方法
export const handle = (async ({ event, resolve }) => { let lang = event.url.startsWith('/fa') ? 'fa' : 'en'; return resolve(event, { transformPageChunk: ({ html }) => html.replace('%lang%', lang) }); }) satisfies Handle;
相关链接
- https://github.com/sveltekit-i18n/lib
- https://github.com/sveltejs/kit/issues/3091
- https://stackoverflow.com/questions/75056619/how-to-set-html-lang-dynamically-for-different-pages-in-sveltekit