Опциональные сегменты

В библиотеке Universal Router маршруты описываются с использованием объектов, содержащих свойства path, action и иногда children. Одним из мощных инструментов для гибкой маршрутизации являются опциональные сегменты. Опциональные сегменты позволяют определить часть URL, которая может присутствовать или отсутствовать, не влияя на корректность маршрута.


Синтаксис опциональных сегментов

Опциональный сегмент обозначается с помощью круглых скобок:

{
  path: '/users(/:id)',
  action: ({ params }) => {
    if (params.id) {
      return `Пользователь с ID: ${params.id}`;
    }
    return 'Список всех пользователей';
  }
}

В этом примере сегмент /:id является опциональным.

  • Если URL /users, то params.id будет undefined.
  • Если URL /users/42, то params.id будет '42'.

Важно: скобки нельзя использовать внутри динамического сегмента (:id), они должны обрамлять весь сегмент вместе с предшествующим слэшем.


Вложенные опциональные сегменты

Universal Router поддерживает вложенные опциональные сегменты. Это позволяет строить сложные маршруты без необходимости создавать множество отдельных записей:

{
  path: '/posts(/:year(/:month))',
  action: ({ params }) => {
    const { year, month } = params;
    if (year && month) return `Посты за ${month}/${year}`;
    if (year) return `Посты за ${year}`;
    return 'Все посты';
  }
}
  • /posts'Все посты'
  • /posts/2026'Посты за 2026'
  • /posts/2026/03'Посты за 03/2026'

Опциональные сегменты могут быть вложены до нескольких уровней, но при этом читаемость маршрутов снижается. Рекомендуется использовать вложения только при необходимости.


Комбинация динамических и статических сегментов

Опциональные сегменты можно комбинировать с фиксированными частями URL:

{
  path: '/shop(/category/:categoryId)',
  action: ({ params }) => {
    return params.categoryId
      ? `Товары в категории ${params.categoryId}`
      : 'Все товары магазина';
  }
}

Здесь category/:categoryId является опциональным, а shop — обязательным сегментом.

  • /shop'Все товары магазина'
  • /shop/category/7'Товары в категории 7'

Это позволяет минимизировать количество маршрутов для схожих страниц и упрощает управление URL.


Работа с query-параметрами и опциональными сегментами

Опциональные сегменты могут быть полезны для маршрутов, которые обрабатывают query-параметры:

{
  path: '/search(/:query)',
  action: ({ params, query }) => {
    const searchQuery = params.query || query.q || '';
    return searchQuery ? `Результаты поиска: ${searchQuery}` : 'Пустой поиск';
  }
}

В данном примере поиск может работать как через путь /search/keyword, так и через query-параметр /search?q=keyword.

  • /search'Пустой поиск'
  • /search/javascript'Результаты поиска: javascript'
  • /search?q=universal'Результаты поиска: universal'

Ограничения и нюансы

  1. Опциональные сегменты должны идти в конце пути. Если попытаться вставить опциональный сегмент в середину пути, Universal Router может некорректно сопоставить маршрут.

  2. Нельзя использовать несколько альтернатив через | внутри скобок, как это делается в RegExp. Опциональность задается только через скобки вокруг сегмента.

  3. Совместимость с children: опциональные сегменты хорошо работают в дереве маршрутов. Вложенные маршруты будут правильно получать params, даже если сегмент отсутствует.

const routes = [
  {
    path: '/profile(/:section)',
    children: [
      {
        path: 'settings',
        action: () => 'Настройки профиля'
      },
      {
        path: 'history',
        action: () => 'История действий'
      }
    ]
  }
];
  • /profile/settings'Настройки профиля'
  • /profile/history'История действий'
  • /profile'Нет действий' (если добавить дефолтное действие в родительский маршрут)

Практические рекомендации

  • Использовать опциональные сегменты для сокращения количества маршрутов, которые отличаются только наличием одного или двух сегментов.
  • Для сложных комбинаций лучше создать отдельные маршруты для читаемости и поддержки.
  • Всегда проверять наличие params, так как опциональные сегменты могут быть undefined.
  • Сохранять простоту маршрутов: слишком глубокие вложенные опциональные сегменты усложняют отладку и поддержку кода.

Опциональные сегменты делают Universal Router гибким и мощным инструментом для управления URL, обеспечивая компактность маршрутов без потери контроля над параметрами и действиями.