Обработка несуществующих путей

Page.js — это лёгкая библиотека для маршрутизации в одностраничных приложениях на JavaScript. Одной из ключевых задач при построении SPA является корректная обработка запросов к несуществующим маршрутам, чтобы пользователь не сталкивался с «пустой страницей» или необработанной ошибкой.


Регистрация маршрутов по умолчанию

Page.js позволяет определить маршрут по умолчанию, который срабатывает, если ни один из заданных маршрутов не совпал с текущим URL. Это реализуется с помощью метода page('*', callback):

page('*', () => {
    document.body.innerHTML = '<h1>404 - Страница не найдена</h1>';
});

Особенности использования:

  • Символ * означает «любой путь».
  • Этот маршрут должен быть зарегистрирован после всех конкретных маршрутов, иначе он будет перехватывать все запросы.
  • Callback-функция получает объект контекста ctx, содержащий информацию о маршруте (например, ctx.path).

Доступ к информации о несущетсвующем пути

При срабатывании маршрута '*' можно использовать объект ctx для анализа URL:

page('*', ctx => {
    console.log('Попытка доступа к:', ctx.path);
    renderNotFoundPage(ctx.path);
});

function renderNotFoundPage(path) {
    document.body.innerHTML = `
        <h1>404 - Страница "${path}" не найдена</h1>
        <p>Проверьте правильность введённого URL.</p>
    `;
}

Ключевые моменты:

  • ctx.path — полный путь запроса.
  • Можно использовать для логирования, аналитики и отправки на сервер уведомлений о 404.

Редирект на главную или другую страницу

Иногда вместо отображения ошибки 404 требуется перенаправление на существующую страницу. Page.js поддерживает редирект через метод page.redirect():

page('*', () => {
    page.redirect('/home');
});

Преимущества подхода:

  • Поддерживает плавную навигацию без перезагрузки страницы.
  • Можно добавить условие, например, редирект только для аутентифицированных пользователей.

Обработка 404 с динамическим контентом

Можно создавать универсальные шаблоны для всех несуществующих маршрутов, включая поиск похожих страниц или ссылки на главные разделы:

page('*', ctx => {
    const suggestions = getPageSuggestions(ctx.path);
    document.body.innerHTML = `
        <h1>404 - Страница "${ctx.path}" не найдена</h1>
        <p>Возможно, вы имели в виду:</p>
        <ul>${suggestions.map(s => `<li><a href="${s.url}">${s.title}</a></li>`).join('')}</ul>
    `;
});

function getPageSuggestions(path) {
    // Простейший пример: поиск по массиву существующих маршрутов
    const pages = [
        { url: '/home', title: 'Главная' },
        { url: '/about', title: 'О нас' },
        { url: '/contact', title: 'Контакты' }
    ];
    return pages.filter(p => p.title.toLowerCase().includes(path.replace('/', '').toLowerCase()));
}

Особенности подхода:

  • Создаёт более дружественный UX.
  • Поддерживает динамическое наполнение, в том числе с использованием API для поиска релевантных страниц.

Использование middleware для обработки несуществующих маршрутов

Page.js позволяет использовать middleware для проверки доступности маршрутов перед их обработкой. Это полезно, если маршруты формируются динамически:

const validPaths = ['/home', '/about', '/contact'];

page('*', ctx => {
    if (!validPaths.includes(ctx.path)) {
        ctx.notFound = true;
    }
    next();
});

page('*', ctx => {
    if (ctx.notFound) {
        document.body.innerHTML = `<h1>404 - Страница "${ctx.path}" не найдена</h1>`;
    }
});

Преимущества:

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

Обработка ошибок при асинхронной загрузке страниц

Если приложение использует асинхронные загрузки компонентов или данных, необходимо учитывать возможные ошибки, чтобы не показывать пустой экран:

page('/profile/:id', async ctx => {
    try {
        const data = await fetchUserProfile(ctx.params.id);
        renderProfile(data);
    } catch (error) {
        document.body.innerHTML = `<h1>Ошибка загрузки страницы</h1>`;
    }
});

В случае, если пользователь попытается попасть на несуществующую страницу, можно комбинировать асинхронную проверку с маршрутом '*':

page('*', async ctx => {
    const exists = await checkPageExists(ctx.path);
    if (!exists) {
        document.body.innerHTML = `<h1>404 - Страница "${ctx.path}" не найдена</h1>`;
    } else {
        page.redirect(ctx.path);
    }
});

Важные рекомендации

  • Всегда регистрировать маршрут '*' в самом конце, после всех конкретных маршрутов.
  • Использовать ctx.path для логирования и анализа несуществующих запросов.
  • Для SPA с большим количеством динамических маршрутов — применять middleware и асинхронную проверку доступности страниц.
  • При редиректе учитывать UX: неожиданный редирект на главную может сбивать пользователя, лучше показывать кастомизированную 404 страницу с подсказками.

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