Как перевести метаданные страницы в Next.js (Pages Router) v16
Перевод метаданных для поиска и социальных сетей
Проблема
Метаданные страницы — заголовки и описания — находятся вне основного содержимого страницы. Они отображаются на вкладках браузера, в закладках, в результатах поисковых систем и в предварительных просмотрах в социальных сетях. Когда метаданные не соответствуют языку страницы, пользователи сталкиваются с резким несоответствием ещё до того, как увидят содержимое. Испанская страница с английским заголовком сбивает посетителей с толку и указывает на низкое качество локализации.
Поисковые системы интерпретируют несоответствие языков как признак низкого качества локализации, что может привести к снижению рейтинга в языковых результатах. Социальные сети отображают неверный язык в предварительных просмотрах ссылок, что снижает вовлечённость международной аудитории. Последовательный перевод на всех уровнях, включая метаданные, необходим для профессионального многоязычного опыта.
Решение
Переводите метаданные страницы, используя те же ресурсы перевода, что и для содержимого страницы. Используйте хук useIntl из react-intl для доступа к переведённым строкам и размещайте их в компоненте <Head> страницы. Это гарантирует, что заголовки и описания будут соответствовать текущей локали в вкладках браузера, результатах поиска и предварительных просмотрах в социальных сетях.
Используя метаданные из тех же каталогов сообщений, что и видимое содержимое, вы сохраняете последовательность и избегаете дублирования усилий по переводу. Этот подход работает как для статических страниц, так и для динамических маршрутов, где метаданные зависят от данных, специфичных для страницы.
Шаги
1. Добавьте сообщения метаданных в ваши файлы перевода
Определите дескрипторы сообщений для заголовков и описаний страниц в ваших каталогах перевода, используя ту же структуру, что и для другого переведённого содержимого.
{
"home.title": "Добро пожаловать в наш магазин",
"home.description": "Откройте для себя удивительные товары по отличным ценам",
"products.title": "Наши товары",
"products.description": "Просмотрите наш полный каталог товаров"
}
Каждая страница, для которой нужны переведённые метаданные, должна иметь соответствующие идентификаторы сообщений для её заголовка и описания.
2. Создайте компонент переведенных метаданных
Используйте хук useIntl для доступа к функции formatMessage, а затем отобразите переведенные строки внутри компонента 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>
</>
);
}
Компонент Head — это React-компонент, встроенный в Next.js, который позволяет изменять <head> страницы. Функция formatMessage возвращает переведенную строку для текущей локали.
3. Добавьте метаданные Open Graph и социальных сетей
Расширьте шаблон, чтобы включить метаданные Open Graph и Twitter Card для предварительного просмотра в социальных сетях.
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>
</>
);
}
Сохранение отформатированных сообщений в переменных позволяет избежать многократного вызова formatMessage для одного и того же перевода и делает JSX более чистым.
4. Обрабатывайте динамические метаданные для страниц с параметрами
Для страниц с динамическими маршрутами объедините параметры маршрута с переведенными строками, чтобы создать контекстные метаданные.
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>
</>
);
}
Описатели сообщений поддерживают интерполяцию переменных, что позволяет вставлять динамические значения, такие как идентификаторы или названия продуктов, в переведенные строки метаданных. Соответствующее сообщение может быть "Продукт {productId} - Наш магазин".