”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 Astro Build 创建通往国际化的动态路线 (i)

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

发布于2024-08-22
浏览:536

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";
---

{m.hello({ name: "Alan" })}

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

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

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

.
└── 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()}/`, '');
---

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






注意事项

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

感谢您阅读本文!如果您有任何疑问,请评论,我很乐意为您解答。

版本声明 本文转载于:https://dev.to/alancpazetto/criando-rotas-dinamicas-para-internacionalizacao-i18n-com-astro-build-1o75?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    称量()和ast.literal_eval()中的Python Security 在使用用户输入时,必须优先确保安全性。强大的Python功能Eval()通常是作为潜在解决方案而出现的,但担心其潜在风险。 This article delves into the differences betwee...
    编程 发布于2025-07-10
  • Go语言垃圾回收如何处理切片内存?
    Go语言垃圾回收如何处理切片内存?
    Garbage Collection in Go Slices: A Detailed AnalysisIn Go, a slice is a dynamic array that references an underlying array.使用切片时,了解垃圾收集行为至关重要,以避免潜在的内存泄...
    编程 发布于2025-07-10
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    postgresql:为每个唯一标识符在postgresql中提取最后一行,您可能需要遇到与数据集合中每个不同标识的信息相关的信息。考虑以下数据:[ 1 2014-02-01 kjkj 在数据集中的每个唯一ID中检索最后一行的信息,您可以在操作员上使用Postgres的有效效率: id dat...
    编程 发布于2025-07-10
  • 在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在JTable中维护jtable单元格渲染后,在JTable中,在JTable中实现自定义单元格渲染和编辑功能可以增强用户体验。但是,至关重要的是要确保即使在编辑操作后也保留所需的格式。在设置用于格式化“价格”列的“价格”列,用户遇到的数字格式丢失的“价格”列的“价格”之后,问题在设置自定义单元格...
    编程 发布于2025-07-10
  • 您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    在javascript console 中显示颜色是可以使用chrome的控制台显示彩色文本,例如红色的redors,for for for for错误消息?回答是的,可以使用CSS将颜色添加到Chrome和Firefox中的控制台显示的消息(版本31或更高版本)中。要实现这一目标,请使用以下模...
    编程 发布于2025-07-10
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
    编程 发布于2025-07-10
  • MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    在两个条件下插入或更新或更新 solution:的答案在于mysql的插入中...在重复键更新语法上。如果不存在匹配行或更新现有行,则此功能强大的功能可以通过插入新行来进行有效的数据操作。如果违反了唯一的密钥约束。实现所需的行为,该表必须具有唯一的键定义(在这种情况下为'名称'...
    编程 发布于2025-07-10
  • Python元类工作原理及类创建与定制
    Python元类工作原理及类创建与定制
    python中的metaclasses是什么? Metaclasses负责在Python中创建类对象。就像类创建实例一样,元类也创建类。他们提供了对类创建过程的控制层,允许自定义类行为和属性。在Python中理解类作为对象的概念,类是描述用于创建新实例或对象的蓝图的对象。这意味着类本身是使用类关...
    编程 发布于2025-07-10
  • 在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    mysql-python安装错误:“ mysql_config找不到”“ 由于缺少MySQL开发库而出现此错误。解决此问题,建议在Ubuntu上使用该分发的存储库。使用以下命令安装Python-MysqldB: sudo apt-get安装python-mysqldb sudo pip in...
    编程 发布于2025-07-10
  • 查找当前执行JavaScript的脚本元素方法
    查找当前执行JavaScript的脚本元素方法
    如何引用当前执行脚本的脚本元素在某些方案中理解问题在某些方案中,开发人员可能需要将其他脚本动态加载其他脚本。但是,如果Head Element尚未完全渲染,则使用document.getElementsbytagname('head')[0] .appendChild(v)的常规方...
    编程 发布于2025-07-10
  • 如何实时捕获和流媒体以进行聊天机器人命令执行?
    如何实时捕获和流媒体以进行聊天机器人命令执行?
    在开发能够执行命令的chatbots的领域中,实时从命令执行实时捕获Stdout,一个常见的需求是能够检索和显示标准输出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    编程 发布于2025-07-10
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-07-10
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 为什么在grid-template-colms中具有100%的显示器,当位置设置为设置的位置时,grid-template-colly修复了?问题: 考虑以下CSS和html: class =“ snippet-code”> g...
    编程 发布于2025-07-10
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-07-10
  • 如何从Google API中检索最新的jQuery库?
    如何从Google API中检索最新的jQuery库?
    从Google APIS 问题中提供的jQuery URL是版本1.2.6。对于检索最新版本,以前有一种使用特定版本编号的替代方法,它是使用以下语法:获取最新版本:未压缩)While these legacy URLs still remain in use, it is recommended ...
    编程 发布于2025-07-10

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3