Mejores prácticas de internacionalización multilingüe de Nextjs+next-intl (enrutador de aplicaciones)
Nextjs tiene dos enrutadores: enrutador de aplicaciones y enrutador de páginas.
Hace algún tiempo, bajo el enrutador Page, nextjs se internacionalizó y resumió:
Pero el enrutador Page será el enrutador que Nextjs eliminará gradualmente. Por lo tanto, recientemente, Nextjs se ha internacionalizado basado en el enrutador de aplicaciones.
1. Selección de la solución de internacionalización Nextjs
1. i18next + reaccionar-i18next + i18next-recursos-al-backend + siguiente-enrutador-i18n
Parece que la mayoría de la gente está usando esto. Lo intenté y fue bastante complicado. Aún no lo logré, así que me di por vencido.
2. reacción-intl del siguiente enrutador i18n
Parecía bastante complicado, pero debido a la sombra de 1, me di por vencido.
3. siguiente-intl
next-intl es una solución de internacionalización completa para nextjs y no requiere otros paquetes de software. Y la configuración es relativamente simple. Más importante aún, lo configuré correctamente y no encontré ningún problema inexplicable.
Así que esto es todo.
2. Estructura del directorio
|aplicación ..[locale] ...layout.js ...page.js |componentes ..LangSwitcher.js |public ..locales ...en ....common.json ...es .... common.json |i18n.js |navigation.js |middleware.js |next.config.js
3. Rutas internacionales
1. navegación.js
Este es un archivo de configuración y los elementos configurados en este archivo se llamarán en algunos otros archivos.
importar { createSharedPathnamesNavigation } desde 'next-intl/navigation'; exportar const locales = ['en', 'de', 'es', 'ja','ko','it','pt']; exportar const localePrefix = 'según sea necesario'; exportar const defaultLocale= "en"; exportar const localeItems= [ { nombre: "inglés", código: "en", iso: "en-US", dir: "ltr" }, { nombre : "español", código: "es", iso: "es-ES", dir: "ltr" }, { nombre: "中文", código: "zh_cn", iso: "zh-CN", dir: " ltr" }, { nombre: "Deutsch", código: "de", iso: "de-DE", dir: "ltr" }, { nombre: "Italiano", código: "it", iso: "it- IT", dir: "ltr" }, { nombre: "日本语", código: "ja", iso: "ja-JP", dir: "ltr" }, { nombre: "한국인", código: "ko ", iso: "ko-KR", dir: "ltr" }, { nombre: "Português", código: "pt", iso: "pt-PT", dir: "ltr" }, ] export const { Enlace , redirigir, usePathname, useRouter } = createSharedPathnamesNavigation({ locales, localePrefix });
2. directorio [local]
Todos los archivos de página en el directorio de la aplicación se colocan en el directorio [locale].
3. Middleware: middleware.js
ilustrar:
Implementar el siguiente estilo de URL
URL de idioma predeterminado:
La página de inicio es: www.xxx.com
La página interior es: www.xxx.com/about
URLs en otros idiomas: (Tomemos el español como ejemplo)
La página de inicio es: www.xxx.com/es
La página interior es: www.xxx.com/es/about
Además, si se ingresa el idioma predeterminado en la URL, por ejemplo, el idioma predeterminado es el inglés, el usuario ingresa la URL: www.xxx.com/en
Luego, irá automáticamente a www.xxx.com
Código:
importar createMiddleware desde "next-intl/middleware"; importar { defaultLocale, localePrefix, locales } desde '@/navigation'; exportar createMiddleware predeterminado({ locales, localePrefix, defaultLocale, localeDetection: false, }); exportar const config = { / / Omitir todas las rutas que no deben internacionalizarse. // Esto omite las carpetas "api", "_next" y todos los archivos // con una extensión (por ejemplo, favicon.ico) matcher: ["/((?!api|_next| .*\\..*).*)"], };
4. Cargar archivos de traducción
1. Traducir archivos
ilustrar
Mis archivos de traducción se colocan en el directorio "público", pero de hecho, los archivos de traducción también se pueden colocar en otros directorios, siempre que la ruta correspondiente esté configurada en el archivo i18n.js.
El archivo de traducción es un archivo json y el archivo json puede estar en formato anidado o no. En última instancia, se hará referencia a ambos de forma ligeramente diferente.
Código (no anidado)
{ "aaa": "hola", }
Código (anidado)
{ "bbb":{ "aaa": "hola", } }
2. Archivo i18n.js
ilustrar:
Este archivo se utiliza para importar archivos de traducción, la clave es configurar la ruta del archivo de traducción, que debe ser coherente con la ruta donde se encuentra su archivo de traducción.
${locale} en la ruta indica el idioma.
código
import { getRequestConfig } from "next-intl/server"; // Crea esta configuración una vez por solicitud y // ponla a disposición de todos los componentes del servidor. export default getRequestConfig(async ({ locale }) => ({ // Cargar traducciones para la configuración regional activa.messages: (await import(`./public/locales/${locale}/common.json`)).default, }));
3. Configuración de next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = {} const withNextIntl = require("next-intl/plugin")("./i18n.js"); module.exports =conNextIntl (siguienteConfig)
5. Implementar la traducción
Código en diseño.js:
importar "./globals.css"; importar { NextIntlClientProvider, useMessages } desde 'next-intl'; importar { locales } desde '@/navigation'; importar encabezado desde '@/components/Header' importar pie de página desde '@/components /Función predeterminada de exportación de pie de página RootLayout({ niños, parámetros: { configuración regional } }) { if (!locales.includes(locale)) { notFound(); } const mensajes = useMessages(); return (
<html lang="{locale}">
<nextintlclientprovider locale="{locale}" messages="{messages}">
<body><header />{niños}<footer /></body>
</nextintlclientprovider>
</html>
);
}
Código en page.js:
La configuración regional del parámetro representa el idioma actual.
Si el archivo de traducción no está anidado, entonces const t = useTranslations();
Si el archivo de traducción está anidado, use algo como: const t = useTranslations("bbb"); según la estructura del archivo y las necesidades reales.
importar { useTranslations } desde 'next-intl'; importar { Link } desde '@/navigation'; exportar la función predeterminada Inicio({ params: { locale } }) { const t = useTranslations(); return (<>
<link href="{"/"}"><h1>{t("aa")}</h1></Link>
</>)
6. Cambiador de idiomas
1. Efecto
Desplácese hacia abajo para seleccionar un idioma y la página actual cambiará a la página en el idioma seleccionado.
2. Código
"use client";
import { useLocale } from "next-intl";
import { localeItems, useRouter, usePathname, defaultLocale } from '@/navigation';
export default function LangSwitcher() {
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
console.log(locale)
const handleChange = (e) => {
router.push(pathname, { locale: e.target.value });
};
return (
<div>
<select
value={locale}
onChange={handleChange}
className="h-8 m-2 p-1 rounded border-current"
>
<option value={locale} > {GetLangData(locale).name}</option>
{localeItems.map((item) => {
if (item.code === locale) return null
return (<option key={item.code} value={item.code}>
{item.name}
</option>)
})}
</select>
</div>
);
}
export function GetLangData(defaultLocale) {
var res = {}
{
localeItems.map(locale => {
if (locale.code === defaultLocale) {
console.log(locale)
res = locale
}
})
}
return res
}
7. Compatible con SEO y motores de búsqueda
1. Metadatos
El enrutador de la aplicación Nextjs genera el título y los metadatos de la página. Probé tres métodos:
La primera forma: úselo directamente en layout.js: expert const metadata={}
La segunda forma: utilizar metadatos generados dinámicamente en page.js
Para referencia:Optimización: Metadatos | Next.js (nextjs.org)
De estas dos maneras, fallé en el título en varios idiomas y en los metadatos. Finalmente, se utilizó el tercer método, que también es el más sencillo y directo.
La tercera forma: escriba la etiqueta de título y la etiqueta Meta directamente en page.js.
Por lo tanto, el código de page.js se cambió a este:
importar { useTranslations } desde 'next-intl'; importar { Link } desde '@/navigation'; exportar la función predeterminada Inicio({ params: { locale } }) { const t = useTranslations(); return (<>
<title>{t("nombre-sitio")}</title>
<meta name="keyword" content="{t("site-name")}"></meta>
<meta name="description" content="{t("descripción del sitio")}"></meta>
<meta property="og:type" content="website"></meta>
<meta property="og:title" content="{t("nombre-sitio")}"></meta>
<meta property="og:description" content="{t("descripción del sitio")}"></meta>
<meta property="og:site_name" content="{t("nombre-sitio")}"></meta>
<meta property="og:image" content="/imagenes/xxx.png"></meta>
<meta property="og:image:width" content="512"></meta>
<meta property="og:image:height" content="512"></meta>
<meta property="og:image:alt" content=""></meta>
<link href="{"/"}"><h1>{t("aa")}</h1></Link>
</>)
2. Navegación multilingüe: facilite a los motores de búsqueda descubrir URL multilingües.
ilustrar
El selector de idiomas se representa en el front-end, por lo que agregué navegación en varios idiomas renderizada en el back-end en la parte inferior de la página, que es el componente Footer.js. Al hacer clic en el idioma correspondiente accederá a la página de inicio del sitio web en ese idioma.
El código Footer.js es el siguiente:
import Link from 'next/link'
import { localeItems,defaultLocale } from '@/navigation';
export default function Footer(){
return (<>
<div className="divider"></div>
<footer className="footer footer-center p-10 bg-base-200 text-base-content rounded">
<nav className="flex flex-wrap gap-4">
{localeItems.map(locale => {
if (locale.code === defaultLocale) return(<Link className="link link-hover" href="/" key={locale.code}>{locale.name}</Link>)
const thehref="/"+locale.code
return (<Link className="link link-hover" href={thehref} key={locale.code}> {locale.name}</Link>)
})}
</nav>
<aside className='p-6 text-center'>
<p>Copyright © 2024 - All right reserved by xxx.com</p>
</aside>
</footer>
</>
)
}
8. Resumen
Enrutamiento internacional, estructura e introducción de archivos de traducción e implementación de la traducción. No importa qué tipo de plan de internacionalización, estos tres aspectos estarán involucrados. Aunque no es problemático, en general, next-intl es relativamente simple.
9. Referencia
Una inmersión profunda en la localización del enrutador de aplicaciones Next.js con next-intl