Catch-all маршруты

Catch-all маршруты (или маршруты «ловушки») представляют собой универсальные маршруты, которые способны обрабатывать все запросы, не совпадающие с более конкретными маршрутами. Их часто используют в веб-приложениях для обработки динамических URL, страниц с ошибкой 404, или маршрутов с переменным числом сегментов.

Синтаксис и особенности

В современных JavaScript-фреймворках, таких как Next.js, catch-all маршруты задаются с использованием квадратных скобок и многоточия:

// Пример для Next.js
/pages/posts/[...slug].js
  • [...slug] указывает, что данный маршрут может соответствовать любому количеству сегментов после /posts/.
  • Значение параметра slug всегда приходит в виде массива строк, где каждый элемент массива соответствует одному сегменту URL:
// Запрос к /posts/2025/12/22/article
slug = ['2025', '12', '22', 'article']
  • Если маршрут совпадает с пустым путем (например, /posts без дополнительных сегментов), массив может быть пустым.

Различие между catch-all и optional catch-all

Optional catch-all маршруты позволяют маршруту совпадать как с пустым путем, так и с любым количеством сегментов. В Next.js это обозначается двумя точками перед многоточием:

/pages/docs/[[...params]].js
  • Совпадение с /docsparams = []
  • Совпадение с /docs/guides/jsparams = ['guides', 'js']

Optional catch-all особенно полезны, когда необходимо обработать как базовый путь, так и все вложенные маршруты одним компонентом.

Примеры использования

  1. Динамические блоги или статьи
export default function Post({ params }) {
    const { slug } = params;

    return (
        <div>
            <h1>Статья: {slug.join('/')}</h1>
        </div>
    );
}

Такой компонент автоматически отображает любую статью по динамическому пути, например /posts/tech/javascript.

  1. Обработка ошибок 404

Catch-all маршрут можно использовать как страницу по умолчанию для всех несуществующих URL:

/pages/[...notFound].js

export default function NotFound() {
    return <h1>Страница не найдена</h1>;
}

Любой запрос, не совпавший с существующими маршрутами, попадет на этот компонент.

  1. Гибкие роуты для каталогов

Для интернет-магазинов или систем документации catch-all маршруты позволяют создавать глубоко вложенные структуры без необходимости вручную описывать каждый маршрут:

/pages/catalog/[...categories].js
  • /catalog/electronicscategories = ['electronics']
  • /catalog/electronics/phonescategories = ['electronics', 'phones']

Взаимодействие с серверной логикой

Catch-all маршруты часто используют совместно с API-запросами:

export async function getServerSideProps({ params }) {
    const { slug } = params;

    const data = await fetch(`https://api.example.com/items/${slug.join('/')}`)
        .then(res => res.json());

    return { props: { data } };
}
  • Данный подход позволяет создавать универсальные страницы для любых глубин вложенности.
  • Обработка массивов сегментов через join('/') упрощает формирование URL для API.

Ограничения и рекомендации

  • Catch-all маршруты должны идти после всех более конкретных маршрутов, иначе они могут перехватывать запросы, предназначенные для других страниц.
  • Для оптимизации маршрутизации стоит минимизировать количество динамических сегментов, так как слишком общие маршруты могут снижать предсказуемость работы приложения.
  • Использование optional catch-all оправдано только там, где базовый путь и вложенные сегменты имеют схожую логику обработки.

Практическая схема работы

  1. Сервер или фреймворк проверяет наличие точного маршрута.
  2. Если точного маршрута нет, проверяется catch-all маршрут.
  3. Параметры передаются в компонент в виде массива.
  4. Компонент решает, как обрабатывать массив сегментов (рендерить страницу, делать редирект, показывать 404).

Catch-all маршруты в JavaScript создают мощный инструмент для построения динамических и гибких маршрутизируемых приложений, обеспечивая обработку любых URL без необходимости ручного описания каждого пути.