Маршруты для ошибок 404

В веб-приложениях, использующих клиентский роутинг на основе Page.js, необходимо корректно обрабатывать ситуации, когда пользователь пытается перейти на несуществующий путь. В таких случаях сервер обычно возвращает страницу 404, но в SPA (Single Page Application) весь роутинг происходит на клиенте, и управление должно быть возложено на библиотеку Page.js.

Page.js позволяет задать маршрут, который будет срабатывать, если ни один другой маршрут не подошёл. Это достигается с помощью символа * или указания маршрута в конце списка всех зарегистрированных маршрутов.


Определение маршрута для 404

Простейший способ — использовать wildcard-маршрут:

page('*', () => {
    document.body.innerHTML = '<h1>404 - Страница не найдена</h1>';
});
  • '*' — специальный символ, который захватывает все пути, не обработанные ранее.
  • Порядок регистрации имеет значение: wildcard должен быть последним после всех специфичных маршрутов. Если разместить его раньше, он перехватит все переходы.

Пример с множественными маршрутами

page('/home', () => {
    document.body.innerHTML = '<h1>Главная страница</h1>';
});

page('/about', () => {
    document.body.innerHTML = '<h1>О проекте</h1>';
});

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

page();

Здесь маршруты /home и /about обрабатываются как обычные, а любой другой путь приводит к странице 404.


Использование отдельного обработчика функции

Для улучшения читаемости кода можно вынести обработку 404 в отдельную функцию:

function show404() {
    const container = document.getElementById('app');
    container.innerHTML = `
        <h1>404</h1>
        <p>Страница не найдена</p>
        <a href="/home" data-link>На главную</a>
    `;
}

page('*', show404);
  • Вынос обработчика повышает поддерживаемость кода, особенно если контент страницы 404 сложный.
  • Можно добавить кнопку или ссылку для возврата на корректный маршрут, улучшая UX.

Совместная работа с сервером

Для SPA важно согласовать поведение сервера и клиента. Если пользователь напрямую вводит URL в браузере, сервер должен отдавать главный HTML-файл приложения, иначе Page.js не сможет отработать маршрут.

Пример настройки сервера на Node.js с Express:

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'public')));

app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(3000, () => console.log('Сервер запущен на порту 3000'));
  • Все пути направляются на index.html, где уже Page.js определяет, какой маршрут отобразить.
  • Клиентский wildcard-маршрут перехватывает любые несуществующие адреса, показывая страницу 404.

Динамическая обработка 404 с логированием

Для больших приложений полезно регистрировать неизвестные маршруты:

page('*', (ctx) => {
    console.warn(`Попытка доступа к несуществующему пути: ${ctx.path}`);
    document.getElementById('app').innerHTML = '<h1>404 - Страница не найдена</h1>';
});
  • ctx.path содержит полный путь, по которому произошёл переход.
  • Можно отправлять такие данные на сервер для аналитики или отслеживания несуществующих URL.

Использование Page.js с параметрами и 404

Иногда нужно различать динамические маршруты и реальные ошибки. Пример:

page('/user/:id', (ctx) => {
    const userId = ctx.params.id;
    fetch(`/api/users/${userId}`)
        .then(res => {
            if (!res.ok) throw new Error('User not found');
            return res.json();
        })
        .then(user => {
            document.getElementById('app').innerHTML = `<h1>${user.name}</h1>`;
        })
        .catch(() => show404());
});

page('*', show404);
  • Сначала проверяется динамический маршрут /user/:id.
  • Если пользователь не найден, вызывается функция show404().
  • Остальные неизвестные маршруты обрабатываются wildcard.

Особенности работы wildcard в Page.js

  1. Последовательность маршрутов критична — специфичные маршруты должны быть выше wildcard.
  2. ctx.params при wildcard всегда пуст. Для логики можно использовать только ctx.path.
  3. Можно комбинировать с middleware для проверки авторизации перед 404.
function authMiddleware(ctx, next) {
    if (!ctx.user) {
        show404();
    } else {
        next();
    }
}

page('/dashboard', authMiddleware, () => {
    document.getElementById('app').innerHTML = '<h1>Панель управления</h1>';
});

page('*', show404);
  • Middleware позволяет гибко управлять доступом и предотвращать нежелательные переходы.

Такой подход к обработке 404 в Page.js обеспечивает безошибочный клиентский роутинг, улучшает UX, упрощает отладку и интеграцию с сервером.