next-intl 4
Esta habilidad cubre next-intl 4.x según se documenta en https://next-intl.dev/docs/getting-started (documentos de la versión 4.14.9). Contiene lo que difiere de lo habitual: valores predeterminados sorprendentes, errores comunes, APIs heredadas y los patrones que la documentación recomienda. Cada afirmación en los archivos de referencia termina con la página de la que proviene.
Cómo navegar
- Lee el inicio rápido y las reglas rápidas a continuación. Capturan los errores más frecuentes.
- Abre el archivo de referencia que coincida con la tarea, desde la tabla al final.
- Cuando el código use
setRequestLocale,requestLocaleomiddleware.ts, lee primero la tabla "Patrones antiguos".
Inicio rápido (App Router)
El App Router es la ruta recomendada. El Pages Router aún tiene soporte; consulta references/setup.md. https://next-intl.dev/docs/getting-started/pages-router
// next.config.ts
import {NextConfig} from 'next';
import createNextIntlPlugin from 'next-intl/plugin';
const nextConfig: NextConfig = {};
const withNextIntl = createNextIntlPlugin();
export default withNextIntl(nextConfig);
https://next-intl.dev/docs/getting-started/app-router
Sin URLs basadas en locale, src/i18n/request.ts resuelve el locale a partir de una preferencia del usuario, una cookie en su forma más simple:
// src/i18n/request.ts
import {cookies} from 'next/headers';
import {getRequestConfig} from 'next-intl/server';
export default getRequestConfig(async () => {
const store = await cookies();
const locale = store.get('locale')?.value || 'en';
return {
locale,
messages: (await import(`../../messages/${locale}.json`)).default
};
});
https://next-intl.dev/docs/getting-started/app-router
// src/app/layout.tsx
import {NextIntlClientProvider} from 'next-intl';
import {getLocale} from 'next-intl/server';
export default async function RootLayout({children}) {
const locale = await getLocale();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider>{children}</NextIntlClientProvider>
</body>
</html>
);
}
https://next-intl.dev/docs/getting-started/app-router , https://next-intl.dev/docs/usage/configuration
import {useTranslations} from 'next-intl';
import {getTranslations} from 'next-intl/server';
export function HomePage() {
const t = useTranslations('HomePage'); // componente no async
return <h1>{t('title')}</h1>;
}
export async function Profile() {
const t = await getTranslations('ProfilePage'); // componente async
return <h1>{t('title')}</h1>;
}
https://next-intl.dev/docs/getting-started/app-router
Para URLs de estilo /en/about, agrega src/i18n/routing.ts, src/proxy.ts, src/i18n/navigation.ts y un segmento [locale] de nivel superior: references/routing.md. https://next-intl.dev/docs/routing/setup
Reglas rápidas
Configuración
- El plugin encuentra
i18n/request.tsensrc/o en la raíz del proyecto (.ts,.tsx,.js,.jsx). En otro lugar, pasa la ruta:createNextIntlPlugin('./somewhere/else/request.ts'). https://next-intl.dev/docs/getting-started/app-router - El ejemplo de la documentación escribe
const locale = 'en'. Reemplázalo con una resolución real (cookie, preferencia del usuario onext/root-params). https://next-intl.dev/docs/getting-started/app-router getRequestConfigse ejecuta una vez por solicitud, durante el renderizado de Server Components, por lo quecookies()yheaders()funcionan allí. https://next-intl.dev/docs/usage/configuration- Establece
timeZoneen la configuración de la solicitud. El valor predeterminado es la zona horaria del entorno de ejecución del servidor. https://next-intl.dev/docs/usage/configuration
Enrutamiento
- Nombra el archivo
src/proxy.tsen Next.js 16. La importación sigue siendocreateMiddlewaredenext-intl/middleware. https://next-intl.dev/docs/routing/setup - Lee el locale con
await rootParams.locale()denext/root-params, valídalo conhasLocale(routing.locales, value), de lo contrarionotFound(). Next.js anterior a 16.3 necesitaexperimental.rootParams. https://next-intl.dev/docs/routing/setup - Importa
Link,redirect,usePathname,useRouterygetPathnamedesde tui18n/navigation.tsen lugar denext/linkonext/navigation. https://next-intl.dev/docs/routing/navigation - Cambia de idioma con
router.replace(pathname, {locale})desde ese módulo.<Link locale>no se pre-extrae, para evitar sobrescribir la cookie de locale. https://next-intl.dev/docs/routing/navigation redirectsiempre toma un locale:redirect({href: '/login', locale}). Escribereturn redirect(...)para que TypeScript reduzca el tipo. https://next-intl.dev/docs/routing/navigation- El comparador predeterminado omite rutas con un punto. Agrega una entrada explícita para rutas como
/users/jane.doe. https://next-intl.dev/docs/routing/middleware
Componentes Cliente (Client Components)
NextIntlClientProvidersin la propiedadmessagesenvía TODOS los mensajes al cliente. Pasamessages={pick(messages, 'Namespace')}omessages={null}para limitarlos. https://next-intl.dev/docs/environments/server-client-components- Prefiere traducir en un Server Component y pasar las etiquetas como propiedades o
childrenal Client Component. https://next-intl.dev/docs/environments/server-client-components onErrorygetMessageFallbackno se pueden pasar desde un Server Component. Establécelos en tu propio proveedor'use client'anidado dentro del del servidor, que sigue heredando locale y mensajes, así que no los pases manualmente. https://next-intl.dev/docs/usage/configuration
Mensajes
- Las claves y los espacios de nombres no pueden contener
., lo que implica anidamiento. Usa solo JSON anidado. https://next-intl.dev/docs/usage/translations - Los nombres de argumentos ICU y los valores de
selectpermiten letras, dígitos y_, sin guiones: mapeaen-GBaen_GB.selectnecesita un casoother. https://next-intl.dev/docs/usage/translations - Las etiquetas de cierre automático necesitan una etiqueta de cierre en los mensajes:
<br></br>. https://next-intl.dev/docs/usage/translations - Usa
getTranslations({locale, namespace})en Server Actions, metadatos y Route Handlers, donde es posible que el locale no se infiera. https://next-intl.dev/docs/environments/actions-metadata-route-handlers
Pruebas
- Vitest con
createNavigation:server.deps.inline: ['next-intl']. Jest:transformIgnorePatterns: ['node_modules/(?!next-intl)/']. next-intl solo es ESM. https://next-intl.dev/docs/environments/testing
Patrones antiguos
| Antiguo | Actual |
|---|---|
src/middleware.ts | src/proxy.ts en Next.js 16, mismo código createMiddleware |
setRequestLocale(locale) al inicio de cada layout y página | next/root-params en i18n/request.ts, el renderizado estático funciona sin él |
getRequestConfig(async ({requestLocale}) => ...) | getRequestConfig(async ({locale}) => ...) con un respaldo de rootParams.locale() |
Claves de mensaje planas "HomePage.title" | Objetos anidados {"HomePage": {"title": ...}} |
t.raw HTML en dangerouslySetInnerHTML | t.rich (React) o t.markup (cadenas), t.raw solo para omitir análisis, sanitizado |
Detalles: references/routing.md y references/messages.md.
Archivos de referencia
| Archivo | Léelo para |
|---|---|
| references/setup.md | Plugin, configuración de solicitud, valores predeterminados del proveedor, locale sin enrutamiento, almacenamiento de mensajes, Pages Router |
| references/routing.md | defineRouting, segmento [locale], proxy.ts, comparador, next/root-params, renderizado estático, localePrefix, dominios, cookie, enlaces alternativos, nombres de ruta localizados, exportación estática, solución de problemas |
| references/navigation.md | createNavigation, Link, useRouter, usePathname, redirect, getPathname, selector de idioma, href tipado |
| references/messages.md | useTranslations, espacios de nombres, plurales y select de ICU, texto enriquecido, t.markup, t.raw, t.has, arreglos, mensajes faltantes, onError, zona horaria, now |
| references/formatting.md | useFormatter: fechas, tiempo relativo, rangos, números, listas, nombres para mostrar, esqueletos ICU, formatos globales |
| references/server-and-client.md | Server vs Client Components, selección de mensajes, metadatos, Server Actions, Zod, Route Handlers, mapa del sitio, imágenes OG, archivos 404 y de error |
| references/extraction.md | useExtracted y getExtracted experimentales, opciones experimental del plugin, archivos PO, precompilación, códecs personalizados, monorepos |
| references/typescript-and-tooling.md | Aumento de AppConfig, argumentos con tipo seguro, pruebas con Jest y Vitest, Storybook, núcleo use-intl, requisitos de tiempo de ejecución, linting, gestión de traducciones, convenciones del agente |
Páginas rastreadas: SOURCES.md.