"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Creando un lenguaje de ruta dinámico para i en Astro Build

Creando un lenguaje de ruta dinámico para i en Astro Build

Publicado el 2024-08-30
Navegar:444

Creating dynamic route language for i in Astro Build

Se quiser ler esse artigo em Portugês clique aqui

Recientemente, comencé a aprender Astro para crear un proyecto similar a un tablero.

Realmente quiero implementar la internacionalización (i18n) en este proyecto; la idea es que todos puedan usarlo, independientemente de su idioma.

Problema

El soporte i18n de Astro es bastante bueno. Funciona de manera similar a Next.js o cualquier otro marco con enrutamiento basado en la estructura de archivos/carpetas.

Entonces, si queremos tener una página en inglés y la misma página en portugués, podemos organizar nuestros archivos de esta manera:

.
└── src/
    └── pages/
        ├── en/
        │   ├── login.astro
        │   └── dashboard.astro
        └── pt-br/
            ├── login.astro
            └── dashboard.astro

Y cada página tiene sus propias cadenas i18n. ¡Genial!

Pero aquí es donde comienza mi problema: no quiero clonar todas mis páginas; Solo quiero cambiar las cadenas de esas páginas.

Necesito algo como /[any-language-flag]/all-my-routes.

Podrías preguntar: "¿Por qué no usar algo como reaccionar-intl?" Mi respuesta es que quiero aprovechar al máximo el motor de Astro, especialmente para SSG/SSR, y evitar cualquier componente del cliente. Generalmente, estos marcos utilizan React Context, que solo se representa en el lado del cliente.

Intentando y fallando

En primer lugar, leí la receta de Astro sobre i18n y revisé algunas bibliotecas comunitarias para resolver este problema.

La primera biblioteca que probé fue astro-i18next, ¡y parecía exactamente lo que necesitaba!

Basado en una matriz en el archivo de configuración, astro-i18next genera mis páginas i18n en el momento de la compilación, por lo que solo necesito codificar una vez y no tengo que preocuparme por clonar páginas.

El problema es que astro-i18next parece estar archivado o ya no se mantiene. Hay muchos problemas y la última confirmación fue hace más de un año.

Solución

Después de probar otras bibliotecas (mención de honor para astro-i18n), encontré Paraglide y cambió las reglas del juego para mi proyecto.

Elegí Parapente porque:

  • Es seguro para escribir, por lo que puedo usarlo con TypeScript y beneficiarme del autocompletado.
  • Convierte cadenas i18n en funciones, por lo que si la clave de una cadena cambia, mi compilación fallará y detectará errores temprano.
  • El uso de las funciones de i18n permite agitar mejor los árboles y eliminar funciones no utilizadas.
  • Existe una extensión de VS Code que mejora la experiencia de desarrollo.

Nota: También puedes usar Paraglide en un proyecto JS y también es compatible con Next.js.

Después de la instalación y configuración, usé mis mensajes como este:

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

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

Sin embargo, esto no resolvió mi problema de enrutamiento; todavía estaba clonando mis páginas para cada idioma que quería agregar.

Para resolver esto, cambié mi proyecto para usar rutas dinámicas en la ruta raíz, por lo que todas mis rutas ahora comienzan con la bandera de idioma.

Mi estructura de carpetas se convirtió en esto:

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

Después de este cambio, Paraglide puede obtener automáticamente el idioma del parámetro de ruta:

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

Ahora puedo agregar un nuevo idioma simplemente configurándolo en astro.config.ts y traduciendo mi archivo de cadena.

Pero todavía tengo dos problemas más que resolver:

  1. Cuando el usuario accede por primera vez a http://localhost:4321/ sin una marca de idioma.
  2. Si el usuario cambia el idioma en una ruta específica, necesito mantenerlo en la misma ruta (por ejemplo, /es/create-account debe redirigir a /pt-br/create-account o /pt-br/criar -conta).

Middleware para redireccionamiento de idioma

Para resolver el primer problema de redirección de idioma, utilicé middlewares Astro.

En src/middleware/index.ts, agregué este código:

import { defineMiddleware } from 'astro:middleware';
import {
  languageTag,
  setLanguageTag,
  type AvailableLanguageTag,
} from '../paraglide/runtime';

export const onRequest = defineMiddleware((context, next) => {
  // Get lang from url param
  const lang = context.params.lang;

  // If changed
  if (lang !== languageTag()) {
    setLanguageTag(lang as AvailableLanguageTag);
    // Redirect to lang changed or default (en)
    return context.redirect(`/${lang ?? 'en'}`);
  }

  return next();
});

Selector de idioma con ruta actual

Para mantener al usuario en la misma ruta cuando cambia de idioma, agregué este componente:

---
import { languageTag } from '../paraglide/runtime';

const pathName = Astro.url.pathname.replace(`/${languageTag()}/`, '');
---

Además, también podríamos traducir estos mensajes, usando el segundo parámetro en la función de mensajes de Paraglide:

Consideraciones

No considero que mi solución sea la mejor, especialmente porque todavía estoy aprendiendo Astro, por lo que podría haber otras soluciones. Si conoce alguno, coméntelo y lo probaré :)

¡Gracias por leer este artículo! Si tienes alguna pregunta, por favor comenta, estaré encantado de responderte.

Declaración de liberación Este artículo se reproduce en: https://dev.to/alancpazetto/creating-dynamic-route-language-for-i18n-in-astro-build-2iim?1 Si hay alguna infracción, comuníquese con [email protected] para borrarlo
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3