Переключение между режимами

Библиотека Navigo поддерживает два основных режима маршрутизации:

  • Hash-based routing (#/path)
  • History API routing (/path)

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


Hash-based режим

Принцип работы

Hash-режим использует часть URL после символа #. Например:

http://example.com/#/about

Все изменения происходят в фрагменте URL, который не отправляется на сервер. Это означает:

  • Сервер всегда получает один и тот же путь (/)
  • Навигация полностью обрабатывается на клиенте

Инициализация

const router = new Navigo('/', { hash: true });

Или в более старом стиле:

const router = new Navigo('/', true);

Особенности

  • Не требует серверной настройки
  • Работает даже при открытии страницы напрямую
  • Поддерживается всеми браузерами, включая устаревшие

Ограничения

  • URL содержит #, что ухудшает читаемость
  • Ограниченные возможности SEO
  • Не соответствует классической структуре URL

History API режим

Принцип работы

History API использует стандартные URL без #:

http://example.com/about

Навигация осуществляется через:

  • history.pushState
  • history.replaceState
  • popstate события

Инициализация

const router = new Navigo('/', { hash: false });

Или:

const router = new Navigo('/');

Особенности

  • Чистые и понятные URL
  • Лучшее восприятие пользователями
  • Поддержка SEO при правильной настройке сервера

Требования

Сервер должен перенаправлять все маршруты на index.html.

Пример для Express:

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

Переключение режимов

Основной параметр

Ключевой параметр — hash:

const router = new Navigo('/', { hash: true });  // Hash режим
const router = new Navigo('/', { hash: false }); // History API

Динамическое переключение

Navigo не поддерживает изменение режима “на лету”. Переключение требует:

  1. Уничтожения текущего роутера
  2. Создания нового экземпляра
router.destroy();

const newRouter = new Navigo('/', { hash: true });

Влияние режима на маршруты

Hash режим

router.on('/about', () => {
  console.log('About page');
});

URL:

http://example.com/#/about

History режим

router.on('/about', () => {
  console.log('About page');
});

URL:

http://example.com/about

Работа с ссылками

Navigo автоматически перехватывает клики по ссылкам.

Пример

<a href="/about" data-navigo>About</a>

В Hash режиме

Ссылка автоматически преобразуется в:

#/about

В History режиме

Остаётся без изменений:

/about

Поведение при обновлении страницы

Hash режим

  • Всегда работает корректно
  • Сервер не участвует в маршрутизации

History режим

  • Требует настройки fallback на сервере
  • Без этого возникает ошибка 404

SEO и индексирование

Hash режим

  • Поисковые системы игнорируют #
  • URL не индексируются как отдельные страницы

History режим

  • Полноценные URL
  • Возможность SSR или prerender
  • Лучшая индексация

Использование базового пути

Navigo позволяет задавать базовый путь:

const router = new Navigo('/app', { hash: false });

Влияние режима

Hash режим

http://example.com/#/app/about

History режим

http://example.com/app/about

Обработка относительных маршрутов

В History режиме важно учитывать базовый путь:

router.on('/profile', handler);

При базе /app:

/app/profile

В Hash режиме:

#/profile

База применяется иначе, так как хэш изолирован.


Совместимость браузеров

Режим Поддержка
Hash Все браузеры
History API IE10+ (частично), современные браузеры

Для старых браузеров рекомендуется Hash режим.


Переключение режима в зависимости от окружения

Практика — выбирать режим динамически:

const useHash = !window.history.pushState;

const router = new Navigo('/', { hash: useHash });

Обработка ошибок маршрутизации

В History режиме ошибка чаще связана с сервером:

router.notFound(() => {
  console.log('404 page');
});

В Hash режиме ошибка — только логическая (маршрут не найден).


Работа с navigate()

Hash режим

router.navigate('/about');

Результат:

#/about

History режим

router.navigate('/about');

Результат:

/about

Взаимодействие с сервером

Hash режим

  • Сервер не участвует
  • Можно использовать даже на статических хостингах без настроек

History режим

Требуется:

  • Rewrite всех маршрутов
  • Настройка SPA fallback

Пример для Nginx:

location / {
  try_files $uri $uri/ /index.html;
}

Кэширование и производительность

Hash режим:

  • Минимальная нагрузка на сервер
  • Весь контроль на клиенте

History режим:

  • Может вызывать лишние запросы при неправильной конфигурации
  • Требует оптимизации сервера

Когда использовать каждый режим

Hash режим подходит, если:

  • Нет доступа к серверу
  • Быстрое прототипирование
  • Поддержка старых браузеров

History режим подходит, если:

  • Важен SEO
  • Есть контроль над сервером
  • Требуется чистый URL

Частые ошибки при переключении

1. Отсутствие серверного fallback

Результат:

404 при обновлении страницы

2. Неверный base path

const router = new Navigo('/app');

Если сервер не настроен — маршруты ломаются.

3. Смешивание режимов

Использование #/path в History режиме или наоборот приводит к некорректной навигации.


Проверка текущего режима

Navigo напрямую не предоставляет метод для получения режима, но можно сохранить настройку:

const config = { hash: true };
const router = new Navigo('/', config);

console.log(config.hash);

Влияние на архитектуру приложения

Выбор режима влияет на:

  • Структуру URL
  • Конфигурацию сервера
  • SEO стратегию
  • Обработку ошибок
  • Поведение навигации

Поэтому решение принимается на раннем этапе разработки и редко меняется позже.