Префиксы локалей

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);
})();

Такой подход позволяет:

  • Автоматически выставлять язык на основе URL.
  • Поддерживать SEO-дружественные URL с явным указанием языка.
  • Сохранять единый набор маршрутов без дублирования логики для каждой локали.

Генерация ссылок с префиксом локали

При построении ссылок важно учитывать текущую локаль:

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 обеспечивает:

  • Чёткую структуру URL для мультиязычных приложений.
  • Удобство и предсказуемость маршрутизации.
  • Лёгкость в поддержке и расширении системы локализации.

Стратегия с динамическим сегментом /:locale позволяет минимизировать дублирование кода и управлять всеми языками из единой структуры маршрутов.