Page.js — это небольшая библиотека для маршрутизации в браузере на
стороне клиента, которая позволяет создавать одностраничные приложения
(SPA) с управлением состоянием URL без перезагрузки страницы. В основе
её работы лежит история браузера и перехват событий
изменения URL с помощью pushState и
popstate.
Ключевые компоненты Page.js:
ctx) — объект, который
передаётся обработчику и содержит параметры URL, query-параметры, путь и
другие данные.page('/home', ctx => {
console.log('Текущий путь:', ctx.path);
});
Для использования Page.js достаточно подключить библиотеку и вызвать
page() с маршрутом. После определения всех маршрутов
вызывается page() без аргументов для запуска
маршрутизатора.
page('/about', ctx => {
document.body.textContent = 'Страница "О нас"';
});
page('/contact', ctx => {
document.body.textContent = 'Страница "Контакты"';
});
page(); // запуск маршрутизатора
По умолчанию Page.js использует HTML5 History API,
что позволяет менять URL без перезагрузки страницы. Если браузер не
поддерживает pushState, библиотека может использовать
хэш-маршрутизацию.
Маршруты в Page.js поддерживают динамические параметры. Параметры
задаются через двоеточие (:), и значения автоматически
попадают в объект ctx.params.
page('/user/:id', ctx => {
console.log(ctx.params.id); // выводит id пользователя
});
Можно использовать несколько параметров в одном маршруте:
page('/post/:category/:id', ctx => {
console.log(ctx.params.category, ctx.params.id);
});
Для необязательных параметров используется знак вопроса:
page('/archive/:year/:month?', ctx => {
console.log(ctx.params.year, ctx.params.month); // month может быть undefined
});
Page.js не парсит query-параметры автоматически, но их можно получить
через ctx.querystring или сторонние утилиты:
page('/search', ctx => {
console.log(ctx.querystring); // "q=javascript&page=2"
});
Для преобразования query-параметров в объект удобно использовать URLSearchParams:
page('/search', ctx => {
const params = new URLSearchParams(ctx.querystring);
console.log(params.get('q')); // "javascript"
});
Контекст маршрута (ctx) содержит:
ctx.path — полный путь запроса.ctx.params — объект параметров маршрута.ctx.querystring — строка query-параметров.ctx.title — можно установить заголовок страницы.ctx.state — пользовательские данные, переданные через
page.show(path, state).Page.js позволяет менять URL без перезагрузки с помощью функции
page.show():
page.show('/about'); // переходит на маршрут "/about"
page.show('/user/123'); // переходит на маршрут с параметром
Можно передавать объект состояния:
page.show('/dashboard', { tab: 'settings' });
При этом состояние будет доступно через ctx.state в
обработчике маршрута.
Page.js поддерживает middleware, которые вызываются перед обработкой маршрута. Это удобно для авторизации, логирования или предварительной подготовки данных.
page('*', ctx => {
console.log('Входящий путь:', ctx.path);
ctx.user = { name: 'Alice' };
});
page('/profile', ctx => {
console.log(ctx.user.name); // "Alice"
});
Можно использовать несколько middleware, которые вызываются последовательно:
page('/dashboard', auth, loadData, ctx => {
renderDashboard(ctx.data);
});
function auth(ctx, next) {
if (!ctx.user) return page.show('/login');
next();
}
function loadData(ctx, next) {
fetch(`/api/data`).then(res => res.json()).then(data => {
ctx.data = data;
next();
});
}
Для тестирования маршрутов без кликов по ссылкам удобно использовать:
page.show('/home'); // инициирует переход
page.dispatch('/home'); // вызывает обработчики маршрута без изменения URL
page.dispatch() полезна, если требуется
симулировать навигацию внутри теста, чтобы проверить
работу middleware и обработчиков маршрутов.
Page.js может автоматически перехватывать клики по ссылкам
<a> с помощью
page.start({ click: true }) (по умолчанию
click: true). Для этого ссылки должны быть внутренними,
относительными, без атрибута target="_blank".
<a href="/about">О нас</a>
При клике страница не перезагрузится, а вызовется соответствующий
обработчик маршрута. Для ссылок с внешним переходом можно использовать
data-no-page:
<a href="https://example.com" data-no-page>Внешняя ссылка</a>
Page.js поддерживает асинхронные операции в middleware через
next():
page('/profile', async (ctx, next) => {
ctx.userData = await fetch(`/api/users/${ctx.params.id}`).then(r => r.json());
next();
});
Важно вызывать next() после завершения асинхронного
кода, иначе маршрутизатор не продолжит цепочку.
Для обработки неопределённых маршрутов используется wildcard
*:
page('*', ctx => {
document.body.textContent = 'Страница не найдена';
});
Если использовать middleware до определения конкретных маршрутов, он сработает для всех переходов.
page('*', logger);
page('/login', loginHandler);
page('/dashboard', auth, loadDashboard);
page('/dashboard/settings', auth, loadSettings);
page('/user/:id', auth, loadUserProfile);
page('*', notFound);
page();
function logger(ctx, next) {
console.log('Переход на:', ctx.path);
next();
}
function auth(ctx, next) {
if (!ctx.user) return page.show('/login');
next();
}
В этом примере реализована цепочка middleware, авторизация, динамические параметры и глобальный логгер.
Page.js обеспечивает простое и мощное управление навигацией, позволяя строить SPA с минимальными усилиями, гибко обрабатывать маршруты, параметры и асинхронные операции, а также тестировать переходы программно.