Cómo traducir los metadatos de página en Next.js (Pages Router) v16
Traduce metadatos para búsqueda y redes sociales
Problema
Los metadatos de página (títulos y descripciones) aparecen fuera del contenido de la página en sí. Se muestran en las pestañas del navegador, marcadores, resultados de motores de búsqueda y vistas previas de redes sociales. Cuando los metadatos no coinciden con el idioma de la página, los usuarios encuentran una inconsistencia discordante antes incluso de ver el contenido. Una página en español con un título en inglés confunde a los visitantes y señala una localización de baja calidad.
Los motores de búsqueda interpretan las discrepancias de idioma como indicadores de localización de baja calidad, lo que potencialmente reduce las clasificaciones en resultados específicos del idioma. Las plataformas de redes sociales muestran el idioma incorrecto en las vistas previas de enlaces, reduciendo la interacción de audiencias internacionales. La traducción consistente en todos los puntos de contacto (incluidos los metadatos) es esencial para una experiencia multilingüe profesional.
Solución
Traduce los metadatos de página utilizando los mismos recursos de traducción que el contenido de la página. Usa el hook useIntl de react-intl para acceder a las cadenas traducidas y colócalas en el componente <Head> de la página. Esto garantiza que los títulos y descripciones coincidan con el idioma actual en las pestañas del navegador, resultados de búsqueda y vistas previas sociales.
Al obtener los metadatos de los mismos catálogos de mensajes que el contenido visible, mantienes la consistencia y evitas duplicar el esfuerzo de traducción. El enfoque funciona tanto para páginas estáticas como para rutas dinámicas donde los metadatos dependen de datos específicos de la página.
Pasos
1. Añade mensajes de metadatos a tus archivos de traducción
Define descriptores de mensajes para títulos y descripciones de página en tus catálogos de traducción, utilizando la misma estructura que otro contenido traducido.
{
"home.title": "Welcome to Our Store",
"home.description": "Discover amazing products at great prices",
"products.title": "Our Products",
"products.description": "Browse our full catalog of items"
}
Cada página que necesite metadatos traducidos debe tener IDs de mensaje correspondientes para su título y descripción.
2. Crea un componente de metadatos traducido
Usa el hook useIntl para acceder a la función formatMessage, luego renderiza las cadenas traducidas dentro del componente Head.
import Head from "next/head";
import { useIntl } from "react-intl";
export default function HomePage() {
const intl = useIntl();
return (
<>
<Head>
<title>{intl.formatMessage({ id: "home.title" })}</title>
<meta
name="description"
content={intl.formatMessage({ id: "home.description" })}
/>
</Head>
<main>
<h1>{intl.formatMessage({ id: "home.title" })}</h1>
</main>
</>
);
}
El componente Head es un componente de React integrado en Next.js que te permite modificar el <head> de una página. La función formatMessage devuelve la cadena traducida para el locale actual.
3. Añade metadatos de Open Graph y redes sociales
Extiende el patrón para incluir metadatos de Open Graph y Twitter Card para las vistas previas en redes sociales.
import Head from "next/head";
import { useIntl } from "react-intl";
export default function ProductsPage() {
const intl = useIntl();
const title = intl.formatMessage({ id: "products.title" });
const description = intl.formatMessage({ id: "products.description" });
return (
<>
<Head>
<title>{title}</title>
<meta name="description" content={description} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
</Head>
<main>
<h1>{title}</h1>
</main>
</>
);
}
Almacenar los mensajes formateados en variables evita llamar a formatMessage múltiples veces para la misma traducción y mantiene el JSX más limpio.
4. Gestiona metadatos dinámicos para páginas parametrizadas
Para páginas con rutas dinámicas, combina los parámetros de ruta con cadenas traducidas para crear metadatos contextuales.
import Head from "next/head";
import { useIntl } from "react-intl";
import { useRouter } from "next/router";
export default function ProductDetailPage() {
const intl = useIntl();
const router = useRouter();
const { id } = router.query;
const title = intl.formatMessage(
{ id: "product.detail.title" },
{ productId: id },
);
return (
<>
<Head>
<title>{title}</title>
</Head>
<main>
<h1>{title}</h1>
</main>
</>
);
}
Los descriptores de mensajes admiten interpolación de variables, lo que te permite inyectar valores dinámicos como IDs de productos o nombres en cadenas de metadatos traducidas. El mensaje correspondiente podría ser "Product {productId} - Our Store".