如果您想阅读这篇英文文章,请前往此处
我最近开始学习 Astro 来创建一个仪表板风格的项目。
我真的很想在这个项目中实现国际化(i18n)——目标是任何人都可以使用它,无论语言如何。
Astro 上的 I18n 支持非常好。它的工作原理类似于 Next.js 或任何其他基于文件/文件夹结构进行路由的框架。
因此,如果我们想要一个英文页面和一个葡萄牙语页面,我们可以这样组织我们的文件:
. └── src/ └── pages/ ├── en/ │ ├── login.astro │ └── dashboard.astro └── pt-br/ ├── login.astro └── dashboard.astro
每个页面都有自己的 i18n 字符串——酷!
但这就是我的问题开始的地方:我不想克隆我的所有页面;我只想更改这些页面上的字符串。
我需要类似 /[any-language-flag]/all-my-routes 的东西。
你可能会问,“为什么不使用像react-intl这样的东西呢?”我的答案是,我想充分利用 Astro 引擎,尤其是 SSG/SSR,并避免使用任何客户端组件。一般来说,这些框架使用React Context,它只在客户端渲染。
首先,我阅读了Astro关于i18n的食谱并查看了一些社区库来解决这个问题。
我尝试的第一个库是 astro-i18next,它看起来正是我需要的!
基于配置文件中的数组,astro-i18next 在构建时生成我的 i18n 页面,因此我只需要编写一次代码,而不必担心克隆页面。
问题是 astro-i18next 似乎已存档或不再维护。有很多问题,最后一次提交已经是一年多前了。
在尝试其他库(astro-i18n 的荣誉奖)后,我找到了 Paraglide,它改变了我的项目。
我选择滑翔伞是因为:
注意:你也可以在JS项目中使用Paraglide,并且它还支持Next.js。
安装和配置后,我使用了这样的消息:
--- import * as m from "../paraglide/messages.js"; ---{m.hello({ name: "Alan" })}
然而,这并没有解决我的路由问题——我仍在为我想要添加的每种语言克隆我的页面。
为了解决这个问题,我将项目更改为在根路由中使用动态路由,因此我的所有路由现在都以语言标志开头。
我的文件夹结构如下所示:
. └── src/ └── pages/ └── [lang]/ ├── login.astro └── dashboard.astro
此次变更后,Paraglide可以自动获取路线参数语言:
现在我只需在 astro.config.ts 中配置它并翻译我的字符串文件即可添加新语言。
但是我还有两个问题需要解决:
为了解决第一个语言重定向问题,我使用了Astro中间件。
在src/middleware/index.ts中,我添加了这段代码:
import { defineMiddleware } from 'astro:middleware'; import { languageTag, setLanguageTag, type AvailableLanguageTag, } from '../paraglide/runtime'; export const onRequest = defineMiddleware((context, next) => { // Obter o idioma do parâmetro da URL const lang = context.params.lang; // Se mudou if (lang !== languageTag()) { setLanguageTag(lang as AvailableLanguageTag); // Redirecionar para o idioma alterado ou padrão (en) return context.redirect(`/${lang ?? 'en'}`); } return next(); });
为了让用户在更改语言时保持相同的路线,我添加了这个组件:
--- import { languageTag } from '../paraglide/runtime'; const pathName = Astro.url.pathname.replace(`/${languageTag()}/`, ''); ---
此外,我们也可以使用 Paraglide 消息函数中的第二个参数来翻译这些消息:
我不认为我的解决方案是最好的,特别是因为我还在学习 Astro,所以可能还有其他解决方案。如果您知道,请评论,我会尝试:)
感谢您阅读本文!如果您有任何疑问,请评论,我很乐意为您解答。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3