Использование с ванильным JavaScript

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

Подключение Page.js

Для использования 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" }.

Обработка query-параметров

Хотя 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 в адресной строке и вызывает соответствующий обработчик маршрута без перезагрузки страницы.

Middleware

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 или конечному обработчику маршрута.

Обработка 404 страницы

Для определения маршрута по умолчанию, когда ни один путь не совпадает, используется символ *.

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>';
});

Это обеспечивает контроль над навигацией и предотвращает нежелательные переходы.

Интеграция с DOM и компонентами

В простых приложениях можно напрямую изменять innerHTML или appendChild. Для более сложных проектов рекомендуется создавать отдельные функции для рендеринга компонентов и вызывать их в обработчиках маршрутов:

function renderHome() {
  const container = document.getElementById('app');
  container.innerHTML = '<h1>Главная страница</h1>';
}

page('/', renderHome);

Такой подход упрощает поддержку и тестирование кода, а также улучшает читаемость структуры приложения.


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