Universal Router — это легковесная библиотека для маршрутизации в JavaScript-приложениях, которая позволяет строить динамическую маршрутизацию с поддержкой асинхронных обработчиков и сложной логики. Одной из частых задач является организация многоязычного интерфейса с возможностью переключения языков. Для этого используются параметры маршрута, контекст и middleware-подобные функции.
Основной подход — включение кода языка в путь URL. Например:
import UniversalRouter from 'universal-router';
const routes = [
{
path: '/:lang',
async action(context) {
const { lang } = context.params;
context.language = lang;
return `Выбран язык: ${lang}`;
}
},
{
path: '/:lang/about',
async action(context) {
return `О сайте на языке ${context.language}`;
}
}
];
const router = new UniversalRouter(routes);
router.resolve({ pathname: '/en/about' }).then(console.log);
Здесь :lang становится динамическим параметром маршрута.
context.params позволяет получить код языка и использовать
его для локализации контента или для выбора соответствующих данных.
Universal Router передаёт объект context каждому
обработчику маршрута. Это позволяет хранить информацию о текущем
языке:
const context = { language: 'ru' };
const routes = [
{
path: '/:lang/home',
async action(ctx) {
ctx.language = ctx.params.lang;
return `Главная страница на ${ctx.language}`;
}
}
];
router.resolve({ pathname: '/en/home', context }).then(console.log);
context.language может использоваться в последующих
маршрутах или для передачи в функции рендеринга. Такой подход упрощает
поддержку глобальной локализации в приложении.
Для крупных приложений полезно создавать маршруты автоматически для каждого поддерживаемого языка:
const supportedLanguages = ['en', 'ru', 'fr'];
const baseRoutes = [
{ path: '/home', name: 'home' },
{ path: '/about', name: 'about' }
];
const routes = supportedLanguages.flatMap(lang =>
baseRoutes.map(route => ({
path: `/${lang}${route.path}`,
async action(ctx) {
ctx.language = lang;
return `Страница ${route.name} на ${lang}`;
}
}))
);
const router = new UniversalRouter(routes);
Такой подход гарантирует наличие маршрутов для всех языков без дублирования логики обработки.
Иногда требуется сменить язык, не меняя основного маршрута. Для этого можно использовать middleware-подобные функции и редирект:
const routes = [
{
path: '/:lang/home',
async action(ctx) {
ctx.language = ctx.params.lang;
return `Главная на ${ctx.language}`;
}
}
];
function changeLanguage(router, currentPath, newLang) {
const newPath = currentPath.replace(/^\/[^/]+/, `/${newLang}`);
return router.resolve({ pathname: newPath });
}
router.resolve({ pathname: '/ru/home' }).then(result => {
console.log(result); // Главная на ru
changeLanguage(router, '/ru/home', 'en').then(console.log); // Главная на en
});
Регулярное выражение ^\/[^/]+ заменяет первый сегмент
пути на новый код языка, сохраняя остальную часть маршрута. Это удобно
для интерфейсов с переключателем языка.
Universal Router не накладывает ограничений на библиотеку
локализации. context.language можно передавать в
i18n-движки, например i18next:
import i18next from 'i18next';
const routes = [
{
path: '/:lang/dashboard',
async action(ctx) {
i18next.changeLanguage(ctx.params.lang);
return i18next.t('dashboard.title');
}
}
];
Каждый переход по маршруту автоматически устанавливает нужный язык в i18n-контексте.
Для пользователей с неизвестным или неподдерживаемым языком полезно устанавливать язык по умолчанию:
const defaultLang = 'en';
const routes = [
{
path: '/:lang?/home',
async action(ctx) {
const lang = ctx.params.lang || defaultLang;
ctx.language = lang;
return `Главная на ${lang}`;
}
}
];
Использование ?: делает сегмент языка необязательным, а
оператор || задаёт fallback. Такой подход повышает
устойчивость приложения к некорректным URL.
Для сложных приложений с подмаршрутами полезно использовать вложенные маршруты:
const routes = [
{
path: '/:lang',
children: [
{ path: '/home', action: ctx => `Главная на ${ctx.params.lang}` },
{ path: '/about', action: ctx => `О сайте на ${ctx.params.lang}` }
]
}
];
const router = new UniversalRouter(routes);
Вложенные маршруты позволяют группировать страницы по языкам и упрощают поддержку динамических путей.
Для крупных приложений с множеством языков часто используется ленивое подгружание переводов:
const routes = [
{
path: '/:lang/home',
async action(ctx) {
const translations = await import(`./locales/${ctx.params.lang}.json`);
return translations.default.homeTitle;
}
}
];
Такой подход минимизирует размер бандла и ускоряет начальную загрузку приложения, подгружая переводы только при необходимости.
:lang для выбора
языка.context.Эти методы обеспечивают гибкую и масштабируемую локализацию с использованием Universal Router, позволяя управлять маршрутами и языковыми ресурсами централизованно и эффективно.