首页  >  文章  >  web前端  >  使用 Astro Build 创建通往国际化的动态路线 (i)

使用 Astro Build 创建通往国际化的动态路线 (i)

WBOY
WBOY原创
2024-08-18 00:00:021068浏览

Criando rotas dinâmicas para internacionalização (i) com Astro Build

如果您想阅读这篇英文文章,请点击这里

我最近开始学习 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,它改变了我的项目。

我选择滑翔伞是因为:

  • 它是类型安全的,因此我可以将它与 TypeScript 一起使用并利用自动完成功能。
  • 它将 i18n 字符串转换为函数,因此如果字符串键发生更改,我的构建将会失败,从而尽早捕获错误。
  • 使用 i18n 函数可以更好地进行树摇动,删除未使用的函数。
  • 有一个 VS Code 扩展,可以改善开发体验。

注意:您也可以在 JS 项目中使用 Paraglide,并且它还支持 Next.js。

安装和配置后,我使用了这样的消息:

---
import * as m from "../paraglide/messages.js";
---

<h1>{m.hello({ name: "Alan" })}</h1>

但是,这并没有解决我的路由问题 - 我仍在为我想要添加的每种语言克隆我的页面。

为了解决这个问题,我将项目更改为在根路由中使用动态路由,因此我的所有路由现在都以语言标志开头。

我的文件夹结构如下所示:

.
└── src/
    └── pages/
        └── [lang]/
            ├── login.astro
            └── dashboard.astro

此更改后,Paraglide 可以自动获取路线参数的语言:

  • http://localhost:4321/en/login
  • http://localhost:4321/pt-br/login

现在我只需在 astro.config.ts 中配置它并翻译我的字符串文件即可添加新语言。

但是我还有两个问题需要解决:

  1. 当用户第一次访问 http://localhost:4321/ 时,没有语言标志。
  2. 如果用户更改特定路线上的语言,我需要将其保持在同一路线上(例如 /en/create-account 应重定向到 /pt-br/create-account 或 /pt-br/criar-account ).

语言重定向中间件

为了解决第一个语言重定向问题,我使用了 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()}/`, '');
---

<ul>
  <li>
    <a href={`/pt-br/${pathName}`}>Ir para Português</a>
  </li>
  <li>
    <a href={`/en/${pathName}`}>Go to English</a>
  </li>
</ul>

此外,我们也可以使用 Paraglide 消息函数中的第二个参数来翻译这些消息:

<ul>
  <li>
    <a href={`/pt-br/${pathName}`}>{m.goToLanguage(undefined, { languageTag: 'pt-br' })}</a>
  </li>
  <li>
    <a href={`/en/${pathName}`}>{m.goToLanguage(undefined, { languageTag: 'en' })}</a>
  </li>
</ul>

注意事项

我不认为我的解决方案是最好的,特别是因为我还在学习 Astro,所以可能还有其他解决方案。如果您知道,请评论,我会尝试:)

感谢您阅读这篇文章!如果有任何疑问,请评论,我很乐意回答。

以上是使用 Astro Build 创建通往国际化的动态路线 (i)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn