Как реализовать маршрутизацию по локали в Next.js (Pages Router) v16
Настройка маршрутизации с языковыми сегментами
Проблема
При создании многоязычного приложения один ключевой вопрос определяет всё остальное: как приложение узнает, на каком языке показывать контент? Без явного механизма URL /about становится неоднозначным — он может вести на контент на любом языке. Пользователи не могут делиться ссылками на определённые языковые версии, а поисковые системы не понимают, какая версия предназначена для какой аудитории. Такая неоднозначность создаёт проблемы и для пользовательского опыта, и для SEO, ведь нет чёткого способа определить или сохранить контент на конкретном языке.
Решение
Добавьте идентификатор языка прямо в путь URL, настроив встроенную поддержку i18n-маршрутизации в Next.js. Укажите поддерживаемые локали и локаль по умолчанию в конфиге Next.js. Next.js автоматически будет обрабатывать маршрутизацию, делая доступными пути вроде /fr/about и /nl-NL/about, а для локали по умолчанию префикс не добавляется. Это делает каждый путь уникальным для определённого языка, устраняя неоднозначность для пользователей и поисковых систем.
Шаги
1. Добавьте конфигурацию i18n в next.config.js
Добавьте настройку i18n в файл next.config.js, чтобы указать, какие локали поддерживает ваше приложение.
module.exports = {
i18n: {
locales: ["en-US", "fr", "nl-NL"],
defaultLocale: "en-US",
},
};
Локали — это UTS Locale Identifiers, стандартизированный формат для определения локалей, обычно состоящий из языка, региона и скрипта, разделённых дефисом. defaultLocale используется при переходе по пути без языкового префикса.
2. Получение информации о локали в страницах
Используйте хук useRouter(), чтобы получить информацию о локали в компонентах страниц.
import { useRouter } from "next/router";
export default function AboutPage() {
const router = useRouter();
const { locale, locales, defaultLocale } = router;
return (
<div>
<h1>About Us</h1>
<p>Current locale: {locale}</p>
</div>
);
}
Свойство locale содержит текущую активную локаль, locales — все настроенные локали, а defaultLocale — локаль по умолчанию.
3. Доступ к локали в функциях получения данных
При предварительном рендеринге страниц с помощью getStaticProps или getServerSideProps информация о локали передаётся в context.
import { GetStaticProps } from "next";
export const getStaticProps: GetStaticProps = async (context) => {
const { locale } = context;
const messages = await import(`../messages/${locale}.json`);
return {
props: {
messages: messages.default,
},
};
};
Это позволяет загружать данные, специфичные для локали, на этапе сборки или по запросу, в зависимости от активной локали.
4. Ссылка между локалями
Используйте next/link с пропсом locale, чтобы перейти на другую локаль.
import Link from "next/link";
export default function LanguageSwitcher() {
return (
<nav>
<Link href="/about" locale="en-US">
English
</Link>
<Link href="/about" locale="fr">
Français
</Link>
<Link href="/about" locale="nl-NL">
Nederlands
</Link>
</nav>
);
}
Если проп locale не указан, при переходах на клиенте используется текущая активная локаль. Проп locale позволяет пользователям менять язык, оставаясь на той же логической странице.
5. Генерация статических путей для всех локалей
При использовании getStaticPaths настроенные локали передаются в параметре context в поле locales, а локаль по умолчанию — в defaultLocale.
import { GetStaticPaths } from "next";
export const getStaticPaths: GetStaticPaths = async (context) => {
const { locales } = context;
const paths = locales.flatMap((locale) => [
{ params: { slug: "getting-started" }, locale },
{ params: { slug: "advanced" }, locale },
]);
return {
paths,
fallback: false,
};
};
Это гарантирует, что все версии ваших динамических страниц для разных локалей будут предварительно сгенерированы на этапе сборки.