В библиотеке Universal Router маршруты описываются с
использованием объектов, содержащих свойства path,
action и иногда children. Одним из мощных
инструментов для гибкой маршрутизации являются опциональные
сегменты. Опциональные сегменты позволяют определить часть URL,
которая может присутствовать или отсутствовать, не влияя на корректность
маршрута.
Опциональный сегмент обозначается с помощью круглых скобок:
{
path: '/users(/:id)',
action: ({ params }) => {
if (params.id) {
return `Пользователь с ID: ${params.id}`;
}
return 'Список всех пользователей';
}
}
В этом примере сегмент /:id является опциональным.
/users, то params.id будет
undefined./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-параметры:
{
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'Опциональные сегменты должны идти в конце пути. Если попытаться вставить опциональный сегмент в середину пути, Universal Router может некорректно сопоставить маршрут.
Нельзя использовать несколько альтернатив через
| внутри скобок, как это делается в RegExp.
Опциональность задается только через скобки вокруг сегмента.
Совместимость с children:
опциональные сегменты хорошо работают в дереве маршрутов. Вложенные
маршруты будут правильно получать params, даже если сегмент
отсутствует.
const routes = [
{
path: '/profile(/:section)',
children: [
{
path: 'settings',
action: () => 'Настройки профиля'
},
{
path: 'history',
action: () => 'История действий'
}
]
}
];
/profile/settings →
'Настройки профиля'/profile/history → 'История действий'/profile → 'Нет действий' (если добавить
дефолтное действие в родительский маршрут)params, так как опциональные
сегменты могут быть undefined.Опциональные сегменты делают Universal Router гибким и мощным инструментом для управления URL, обеспечивая компактность маршрутов без потери контроля над параметрами и действиями.