Как перевести метаданные страницы в TanStack Start v1
Перевод метаданных для поиска и социальных сетей
Проблема
Метаданные страницы — заголовки и описания — отображаются на вкладках браузера, в закладках, результатах поиска и предварительных просмотрах в социальных сетях. Когда язык метаданных не совпадает с языком содержимого страницы, пользователи сталкиваются с резким несоответствием ещё до того, как откроют страницу. Испанская страница с английским заголовком в результатах поиска сигнализирует о низком качестве локализации. Поисковые системы могут интерпретировать это несоответствие как сигнал для ранжирования, что потенциально снижает видимость в языковых результатах поиска.
Это несоответствие подрывает пользовательский опыт на этапе обнаружения. Пользователи, ищущие на своём предпочтительном языке, ожидают, что метаданные будут соответствовать, и несоответствие подрывает доверие ещё до первого клика.
Решение
Переводите метаданные страницы, используя те же ресурсы перевода, что и для содержимого страницы. Определите функцию head в конфигурации маршрута, которая получает переведённые строки и возвращает локализованные метаданные заголовка и описания. Это обеспечивает согласованность между тем, что отображается в интерфейсе браузера, результатах поиска и на самой странице.
Используя форматирование сообщений react-intl в функции head, метаданные остаются синхронизированными с вашим процессом перевода и автоматически обновляются при изменении локали.
Шаги
1. Создайте вспомогательную функцию для форматирования сообщений вне компонентов React
Функция head выполняется вне дерева компонентов React, где хуки недоступны. Создайте утилиту, которая форматирует сообщения с использованием createIntl из 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);
}
Этот вспомогательный инструмент создаёт экземпляр intl по запросу для использования в контекстах вне React, таких как функция head.
2. Определите ключи перевода метаданных
Добавьте ключи для заголовков и описаний в ваши файлы перевода для каждой страницы, которая требует локализованных метаданных.
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",
};
Эти ключи следуют той же структуре, что и переводы компонентов, сохраняя весь локализованный контент в одном месте.
3. Добавьте функцию head в ваш маршрут
Используйте опцию head в createFileRoute, чтобы возвращать переведенные метаданные. Получите текущую локаль из параметров маршрута или данных загрузчика, затем форматируйте сообщения с помощью вашего помощника.
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>;
}
Функция head запускается во время сопоставления маршрута и возвращает объекты метаданных, которые TanStack Start рендерит в заголовок документа.
4. Используйте данные загрузчика для динамических метаданных
Когда метаданные зависят от полученных данных, используйте loaderData в функции head, чтобы комбинировать динамический контент с переведенными шаблонами.
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>;
}
Загрузчик получает данные до того, как функция head запускается, что позволяет вам вставлять динамические значения в переведенные шаблоны метаданных.