Cómo traducir los metadatos de página en TanStack Start v1
Traduce metadatos para búsqueda y redes sociales
Problema
Los metadatos de página (títulos y descripciones) aparecen en las pestañas del navegador, marcadores, resultados de búsqueda y vistas previas de redes sociales. Cuando el idioma de los metadatos no coincide con el idioma del contenido de la página, los usuarios experimentan una inconsistencia discordante incluso antes de ver la página. Una página en español con un título en inglés en los resultados de búsqueda señala una localización de baja calidad. Los motores de búsqueda pueden interpretar esta discrepancia como una señal de clasificación, reduciendo potencialmente la visibilidad en resultados de búsqueda específicos del idioma.
Esta desconexión socava la experiencia del usuario en la etapa de descubrimiento. Los usuarios que buscan en su idioma preferido esperan que los metadatos coincidan, y la inconsistencia erosiona la confianza antes del primer clic.
Solución
Traduce los metadatos de página utilizando los mismos recursos de traducción que el contenido de la página. Define una función head en la configuración de tu ruta que acceda a las cadenas traducidas y devuelva metadatos de título y descripción localizados. Esto garantiza la coherencia entre lo que aparece en el navegador, los resultados de búsqueda y la página renderizada.
Al utilizar el formateo de mensajes de react-intl dentro de la función head, los metadatos permanecen sincronizados con tu flujo de trabajo de traducción y se actualizan automáticamente cuando cambia la configuración regional.
Pasos
1. Crea un helper para formatear mensajes fuera de los componentes de React
La función head se ejecuta fuera del árbol de componentes de React donde los hooks no están disponibles. Crea una utilidad que formatee mensajes utilizando createIntl de react-intl.
import { createIntl, createIntlCache } from "react-intl";
const cache = createIntlCache();
export function formatMetadataMessage(
locale: string,
messages: Record<string, string>,
id: string,
values?: Record<string, string | number>,
): string {
const intl = createIntl({ locale, messages }, cache);
return intl.formatMessage({ id }, values);
}
Este helper crea una instancia de intl bajo demanda para su uso en contextos no React como la función head.
2. Define las claves de traducción de metadatos
Añade claves de título y descripción a tus archivos de traducción para cada página que necesite metadatos localizados.
export const enMessages = {
"page.home.title": "Welcome to Our Site",
"page.home.description": "Discover amazing content in your language",
"page.about.title": "About Us",
"page.about.description": "Learn more about our mission and team",
};
export const esMessages = {
"page.home.title": "Bienvenido a Nuestro Sitio",
"page.home.description": "Descubre contenido increíble en tu idioma",
"page.about.title": "Acerca de Nosotros",
"page.about.description": "Conoce más sobre nuestra misión y equipo",
};
Estas claves siguen el mismo patrón que las traducciones de tus componentes, manteniendo todo el contenido localizado en un solo lugar.
3. Añade una función head a tu ruta
Utiliza la opción head en createFileRoute para devolver metadatos traducidos. Accede al locale actual desde los parámetros de ruta o los datos del loader, luego formatea los mensajes usando tu helper.
import { createFileRoute } from "@tanstack/react-router";
import { formatMetadataMessage } from "../utils/formatMetadataMessage";
import { enMessages, esMessages } from "../i18n/messages";
const messagesByLocale = {
en: enMessages,
es: esMessages,
};
export const Route = createFileRoute("/$locale/about")({
head: ({ params }) => {
const locale = params.locale || "en";
const messages = messagesByLocale[locale] || messagesByLocale.en;
return {
meta: [
{
title: formatMetadataMessage(locale, messages, "page.about.title"),
},
{
name: "description",
content: formatMetadataMessage(
locale,
messages,
"page.about.description",
),
},
],
};
},
component: AboutPage,
});
function AboutPage() {
return <div>About content</div>;
}
La función head se ejecuta durante la coincidencia de rutas y devuelve objetos de metadatos que TanStack Start renderiza en el head del documento.
4. Utiliza datos del loader para metadatos dinámicos
Cuando los metadatos dependen de datos obtenidos, accede a loaderData en la función head para combinar contenido dinámico con plantillas traducidas.
import { createFileRoute } from "@tanstack/react-router";
import { formatMetadataMessage } from "../utils/formatMetadataMessage";
import { enMessages, esMessages } from "../i18n/messages";
const messagesByLocale = {
en: enMessages,
es: esMessages,
};
export const Route = createFileRoute("/$locale/posts/$postId")({
loader: async ({ params }) => {
const post = await fetchPost(params.postId);
return { post };
},
head: ({ params, loaderData }) => {
const locale = params.locale || "en";
const messages = messagesByLocale[locale] || messagesByLocale.en;
const { post } = loaderData;
return {
meta: [
{
title: formatMetadataMessage(locale, messages, "page.post.title", {
title: post.title,
}),
},
{
name: "description",
content: post.excerpt,
},
],
};
},
component: PostPage,
});
function PostPage() {
const { post } = Route.useLoaderData();
return <article>{post.content}</article>;
}
El loader obtiene los datos antes de que se ejecute la función head, lo que te permite interpolar valores dinámicos en plantillas de metadatos traducidas.