Как реализовать маршрутизацию на основе локали в 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, стандартизированный формат для определения локалей, который обычно состоит из языка, региона и скрипта, разделенных дефисом. Локаль по умолчанию используется при посещении пути без префикса локали.
2. Получите информацию о локали на страницах
Используйте хук useRouter() для получения информации о локали в компонентах страниц.
import { useRouter } from "next/router";
export default function AboutPage() {
const router = useRouter();
const { locale, locales, defaultLocale } = router;
return (
<div>
<h1>О нас</h1>
<p>Текущая локаль: {locale}</p>
</div>
);
}
Свойство locale содержит текущую активную локаль, locales содержит все настроенные локали, а defaultLocale содержит настроенную локаль по умолчанию.
3. Доступ к локали в функциях получения данных
При предварительном рендеринге страниц с использованием getStaticProps или getServerSideProps информация о локали предоставляется в контексте.
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 настроенные локали предоставляются в параметре контекста под 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,
};
};
Это гарантирует, что все версии ваших динамических страниц для разных локалей будут предварительно отрендерены во время сборки.