Universal Router — это гибкая библиотека маршрутизации для JavaScript, которая позволяет управлять навигацией на клиенте и сервере. Одним из распространённых подходов при разработке мультиязычных приложений является использование префиксов локалей в URL для определения текущего языка. Это особенно важно для SEO и удобства пользователей, так как позволяет иметь единый набор маршрутов с разными языковыми версиями.
Префикс локали — это часть URL, которая указывает на язык приложения. Например:
/en/products/42
/ru/products/42
/fr/products/42
Здесь en, ru, fr — префиксы
локалей для английского, русского и французского языков соответственно.
В Universal Router маршруты можно структурировать так, чтобы префикс
локали был родительским сегментом, под которым
размещаются все остальные маршруты.
import UniversalRouter from 'universal-router';
const routes = [
{
path: '/:locale(en|ru|fr)',
async action(context) {
context.locale = context.params.locale;
return context;
},
children: [
{
path: '',
action: () => 'Главная страница',
},
{
path: 'products',
action: () => 'Список продуктов',
},
{
path: 'products/:id',
action: (context) => `Детали продукта ${context.params.id}`,
},
],
},
];
В этом примере:
/:locale(en|ru|fr) — динамический сегмент, который
сопоставляется с одним из разрешённых языков.children — дочерние маршруты, которые наследуют префикс
локали.context.params.locale сохраняет текущую локаль для
дальнейшего использования в компоненте или шаблоне.Для мультиязычных приложений полезно автоматически определять локаль пользователя и перенаправлять его на соответствующий префикс:
const defaultLocale = 'en';
async function detectLocale(pathname) {
const match = pathname.match(/^\/(en|ru|fr)/);
return match ? match[1] : defaultLocale;
}
const router = new UniversalRouter(routes);
(async () => {
const currentLocale = await detectLocale(window.location.pathname);
const route = await router.resolve({ pathname: window.location.pathname });
console.log(route);
})();
Такой подход позволяет:
При построении ссылок важно учитывать текущую локаль:
function createLink(path, locale) {
return `/${locale}${path.startsWith('/') ? path : '/' + path}`;
}
const productLink = createLink('/products/42', 'ru');
// Результат: /ru/products/42
Использование такой функции гарантирует консистентность URL и корректную маршрутизацию.
Если пользователь заходит на URL без префикса локали, можно использовать редирект на локаль по умолчанию:
{
path: '/',
action: () => ({ redirect: `/${defaultLocale}` })
}
Universal Router позволяет вернуть объект
{ redirect: '/ru' } в action, что удобно для
перенаправления на соответствующий язык.
Дочерние маршруты автоматически наследуют префикс локали. Это значит, что можно структурировать роуты по логике приложения, а не по языкам:
{
path: '/:locale(en|ru)',
children: [
{ path: 'about', action: () => 'О нас' },
{ path: 'contact', action: () => 'Контакты' },
{
path: 'products',
children: [
{ path: '', action: () => 'Список продуктов' },
{ path: ':id', action: (ctx) => `Продукт ${ctx.params.id}` },
]
}
]
}
Такой подход упрощает поддержку и добавление новых языков без необходимости дублировать все маршруты для каждого префикса локали.
Использование context.locale внутри action
позволяет:
async action(context) {
const translations = await loadTranslations(context.locale);
return renderPage({ title: translations.homeTitle });
}
Использование префиксов локалей в Universal Router обеспечивает:
Стратегия с динамическим сегментом /:locale позволяет
минимизировать дублирование кода и управлять всеми языками из единой
структуры маршрутов.