Page.js — это клиентская библиотека для маршрутизации, которая позволяет организовывать навигацию по одностраничным приложениям (SPA) без перезагрузки страницы. Она работает с History API браузера и предоставляет удобный интерфейс для определения маршрутов, обработки параметров и управления переходами между страницами.
Для использования Page.js в проекте на ванильном JavaScript можно подключить библиотеку через CDN:
<script src="https://unpkg.com/page/page.js"></script>
После подключения объект page становится доступен в
глобальной области видимости, что позволяет настраивать маршруты и их
обработчики.
Маршруты в Page.js определяются с помощью метода
page(path, callback), где path — путь
маршрута, а callback — функция, вызываемая при совпадении
URL.
page('/', () => {
document.body.innerHTML = '<h1>Главная страница</h1>';
});
page('/about', () => {
document.body.innerHTML = '<h1>О проекте</h1>';
});
page();
Важно вызвать page() без аргументов после определения
всех маршрутов. Это инициализирует маршрутизацию и обрабатывает текущий
URL.
Page.js позволяет захватывать динамические сегменты URL через
двоеточие (:). Эти параметры передаются в объект
ctx.params.
page('/user/:id', ctx => {
document.body.innerHTML = `<h1>Профиль пользователя ${ctx.params.id}</h1>`;
});
При переходе на /user/42 объект ctx.params
будет содержать { id: "42" }.
Хотя Page.js напрямую не парсит query-параметры, объект
ctx.querystring предоставляет строку запроса. Для удобной
работы можно использовать URLSearchParams.
page('/search', ctx => {
const params = new URLSearchParams(ctx.querystring);
const query = params.get('q');
document.body.innerHTML = `<h1>Результаты поиска: ${query}</h1>`;
});
Переход на /search?q=pagejs выведет “Результаты поиска:
pagejs”.
Переход между маршрутами можно выполнять программно с помощью метода
page(path). Это заменяет стандартное обновление
страницы.
document.getElementById('go-about').addEventListener('click', () => {
page('/about');
});
Этот метод корректно обновляет URL в адресной строке и вызывает соответствующий обработчик маршрута без перезагрузки страницы.
Page.js поддерживает концепцию middleware — функций, которые выполняются перед обработкой маршрута. Они позволяют выполнять авторизацию, логирование или модификацию контекста.
function auth(ctx, next) {
if (!ctx.user) {
page('/login');
} else {
next();
}
}
page('/dashboard', auth, ctx => {
document.body.innerHTML = '<h1>Панель управления</h1>';
});
Функция next() передает управление следующему middleware
или конечному обработчику маршрута.
Для определения маршрута по умолчанию, когда ни один путь не
совпадает, используется символ *.
page('*', () => {
document.body.innerHTML = '<h1>Страница не найдена</h1>';
});
Этот маршрут следует определять после всех остальных маршрутов, чтобы он срабатывал только при отсутствии совпадений.
Page.js использует History API, что позволяет управлять состоянием
браузера без перезагрузки страницы. При необходимости можно отключить
использование pushState и перейти на
hash-маршрутизацию:
page({
hashbang: true
});
При hashbang: true URL будет использовать символ
# перед путём маршрута (/#/about).
Для SPA с несколькими вложенными маршрутами удобно использовать комбинацию middleware и динамических сегментов:
page('/blog', ctx => {
document.body.innerHTML = '<h1>Блог</h1>';
});
page('/blog/:slug', ctx => {
document.body.innerHTML = `<h1>Статья: ${ctx.params.slug}</h1>`;
});
page('/blog/:slug/edit', ctx => {
document.body.innerHTML = `<h1>Редактирование статьи: ${ctx.params.slug}</h1>`;
});
Такой подход позволяет легко расширять приложение и поддерживать иерархию маршрутов.
Page.js предоставляет возможность отменять текущий маршрут, если
необходимо, используя ctx.preventDefault() внутри
middleware:
function checkAccess(ctx, next) {
if (!ctx.user) {
ctx.preventDefault();
page('/login');
} else {
next();
}
}
page('/settings', checkAccess, ctx => {
document.body.innerHTML = '<h1>Настройки</h1>';
});
Это обеспечивает контроль над навигацией и предотвращает нежелательные переходы.
В простых приложениях можно напрямую изменять innerHTML
или appendChild. Для более сложных проектов рекомендуется
создавать отдельные функции для рендеринга компонентов и вызывать их в
обработчиках маршрутов:
function renderHome() {
const container = document.getElementById('app');
container.innerHTML = '<h1>Главная страница</h1>';
}
page('/', renderHome);
Такой подход упрощает поддержку и тестирование кода, а также улучшает читаемость структуры приложения.
Page.js в сочетании с ванильным JavaScript предоставляет легкий и гибкий способ управления маршрутизацией в одностраничных приложениях, позволяя строить динамические интерфейсы без сложных фреймворков.