Infoxicator.com

Traduciendo Mi Blog Con Next.js

Publicado
cover image

El inglés es mi segundo idioma y antes de dominar este idioma, siempre me resultó muy difícil encontrar recursos tecnológicos en mi propio idioma. Por eso decidí traducir mi blog y tener todo mi contenido disponible en español e inglés

translate-gif

Internationalización con Next.js

Next.js ha facilitado la internacionalización (i18n) de sitios web con una de las nuevas funciones avanzadas disponibles en la versión 10: Enrutamiento internacionalizado.

De las dos opciones proporcionadas por Next.js, he decidido usar Sub-path Routing en lugar de Domain Routing ya que no quiero crear un subdominio para la versión en español de mi blog.

Configuración Básica

next.config.js

module.exports = {
    i18n: {
      locales: ['en', 'es'],
      defaultLocale: 'en',
    },
  }

Esta es la única configuración necesaria para habilitar la “Detección automática de idioma”.

El sistema de detección automática de idioma proporcionado por Next.js redirigirá a los usuarios a la ruta con prefíjo /es si el navegador está configurado en español (o cualquiera de sus variaciones regionales) como idioma predeterminado. Next.js examinará el HTTP Header Accept-Language e intentará seleccionar el idioma correcto, sin embargo, si el idioma no coincide, utilizará el idioma predeterminado. Por ejemplo, si los usuarios tienen alemán (DE-de) como idioma en su navegador, seleccionará el idioma predeterminado en inglés (en).

Archivos de Traducción de Idioma

Next.js no prescribe una forma de almacenar los datos de traducción para cada idioma, o qué librería de i18n se puede usar (o si necesita una librería).

Para proyectos pequeños (como en mi caso), un archivo JSON simple es suficiente, sin embargo, para una aplicación grande, se recomienda una solución más robusta para evitar cosas como un paquete inflado.

Creemos una carpeta llamada locale y agreguémos un solo archivo JSON por idioma. es decir, locale/en.json y locale/es.json

{
  "greeting": "Hola amigos!"
}

Podríamos usar la clave del objeto para obtener el valor de la frase traducido sin ninguna librería, sin embargo, quiero usar react-intl ya que es una de las librerías i18n más populares que existen.

Agrega la siguiente configuración a tu _app.js

import '../styles/index.css'
import { IntlProvider } from 'react-intl';
import { useRouter } from "next/router"

const languages = {
  en: require('../locale/en.json'),
  es: require('../locale/es.json')
};

function MyApp({ Component, pageProps }) {
  const router = useRouter()
  const { locale, defaultLocale } = router;
  const messages = languages[locale];
  return <IntlProvider messages={messages} locale={locale} defaultLocale={defaultLocale}>
      <Component {...pageProps} />
      </IntlProvider>
}

export default MyApp

En el código anterior, estamos encapsulando toda nuestra aplicación con IntlProvider y pasando los mensajes y la configuración del idioma que obtuvimos del useRouter() hook. Ahora podemos usar los componentes de react-intl como FormatedMessage en toda nuestra aplicación.

import { FormattedMessage } from 'react-intl'

export default function Greeting() {
return (
  <h1><FormattedMessage id="greeting" /></h1>
)}

Cambiando de Idioma

Al cambiar de idioma, quiero conservar la selección del usuario, de modo que si vuelve a visitar mi blog, el idioma preferido será seleccionado en lugar de la configuración detectada automáticamente por Next.js.

Para lograr esto, podemos usar la cookie de configuración: Next.js Locale Cookie:

import { useRouter } from "next/router"
import { useCookies } from 'react-cookie';

export default function LanguageSwitcher() {
  const [ cookie, setCookie ] = useCookies(['NEXT_LOCALE']);
  const router = useRouter();
  const { locale } = router;

  const switchLanguage = (e) => {
    const locale = e.target.value;
    router.push('/','/', { locale });
    if(cookie.NEXT_LOCALE !== locale){
      setCookie("NEXT_LOCALE", locale, { path: "/" });
    }
  }

  return (
    <select
      onChange={switchLanguage}
      defaultValue={locale}
    >
      <option value="en">EN</option>
      <option value="es">ES</option>
    </select>
  );
}

getStaticProps Para Cada Idioma

Para renderizar la lista de los artículos de mi blog en el idioma seleccionado, el parámetro locale estará disponible en getStaticProps para que se pueda pasar a la función que provee la información de la lista de artículos.

Por Ejemplo:

export async function getStaticProps({ locale }) {
  const allPosts = await getAllPostsForHome(locale)
  return {
    props: { allPosts },
  }
}


Optimización de motores de búsqueda (SEO)

Next.js agregará un atributo HTML global llamado lang a su sitio con la configuración del idioma actual; sin embargo, si tienes un archivo _document.js personalizado, asegúrese de eliminar el valor de lang.

Para informar a los motores de búsqueda sobre versiones alternativas de los artículos en diferentes idiomas, debemos agregar un metatag llamado hreflang por cada idioma disponible (incluido el idioma original) en el head de cada artículo.

Por Ejemplo:

import Head from 'next/head'

export default function Post({ post }) {
return (
...
  <article>
    <Head>
        <link rel="alternate" hreflang={locale} href={`${SITE_URL}${locale}/${post?.slug}`} />
        <link rel="alternate" hreflang={altLocale} href={`${SITE_URL}${altLocale}/${altPost?.slug}`} />
    </Head>
  </article>
...
)}

Conclusión

La internacionalización (i (18 letras) n) solía ser una tarea compleja, sin embargo, con la ayuda de Meta-Frameworks como Next.js y librerías como react-intl, traducir contenido para nuestros usuarios nunca ha sido más fácil! .

Espero que disfruten de mi contenido (traducido) y para mis amigos de habla inglesa, See you laters alligators…


Artículos Recientes

Programación AHA

“Avoid Hasty Abstractions” que traducido seria: “Evite las abstracciones apresuradas”

Reglas de los Micro-Frontends

Esta es una lista con las mejores prácticas para diseñar aplicaciones que siguen el patrón Micro-frontend

Dark Mode No es Suficiente! Esta es una alternativa…

En estos días, la mayoría de los sitios web tienen la opción de alternar el modo oscuro, pero ¿y si quisiera más?