Типичные проблемы и решения

Неправильная инициализация маршрутизатора

Одной из наиболее частых ошибок является некорректная инициализация экземпляра Navigo. Например:

const router = new Navigo(); // ❌ без указания корня маршрутов

Если проект размещается не в корне сайта, важно передать базовый путь:

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

Ключевые моменты:

  • Первый аргумент конструктора — базовый путь. Если приложение на поддомене или вложенной папке, нужно указать правильный путь.
  • Опция hash: true переводит маршрутизацию в hash mode, что полезно при работе на статических серверах без настройки URL rewrite.

Конфликты между динамическими и статическими маршрутами

Когда одновременно используются статические и динамические маршруты, Navigo может неправильно сопоставлять URL. Пример:

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

Проблема: при переходе на /about вызывается обработчик динамического маршрута, а не статический.

Решение: использовать приоритет маршрутов, регистрируя статические раньше динамических или используя регулярные выражения:

router
  .on('/about', () => console.log('About'))
  .on('/:page(?!about)', (params) => console.log(params.page));

Ключевые моменты:

  • Порядок регистрации маршрутов критичен.
  • Регулярные выражения позволяют исключать конкретные пути из динамических маршрутов.

Отсутствие обновления маршрута при изменении URL вручную

Если изменяется адрес в браузере без вызова Navigo (router.navigate), маршрутизатор может не отрабатывать обработчик.

// Проблема
window.location.href = '/contact'; // Navigo не отрабатывает

Решение: использовать встроенный метод router.resolve() после изменения URL:

window.history.pushState({}, '', '/contact');
router.resolve();

Ключевые моменты:

  • router.resolve() проверяет текущий URL и вызывает соответствующий обработчик.
  • Важная практика при интеграции с библиотеками, которые напрямую управляют историей браузера.

Некорректная работа с параметрами

Динамические маршруты позволяют получать параметры, но часто возникает ошибка при ожидании вложенных параметров:

router.on('/user/:id/profile/:section', (params) => {
  console.log(params.id, params.section);
});

Если URL /user/123/profileparams.section будет undefined.

Решение: предусматривать обязательные и необязательные параметры через ? или регулярные выражения:

router.on('/user/:id/profile/:section?', (params) => {
  console.log(params.id, params.section || 'overview');
});

Ключевые моменты:

  • В Navigo необязательные параметры обозначаются знаком ?.
  • Можно задавать значения по умолчанию, чтобы избежать ошибок.

Ошибки при работе с hash-mode и History API

При включенном hash-mode URL имеет вид /#/path, а без него — /path. Часто разработчики смешивают подходы.

Проблемы:

  • Некорректное определение базового пути при переходе между hash и non-hash URL.
  • Невызов обработчика при прямом обновлении страницы.

Решение:

  • Для статических сайтов использовать hash: true.
  • Для SPA на сервере с поддержкой History API — использовать без hash, но убедиться, что сервер корректно обрабатывает все маршруты на одну точку входа.
const router = new Navigo('/', { hash: false });

Ключевые моменты:

  • Hash-mode обеспечивает простую маршрутизацию без серверной настройки.
  • History API удобнее для SEO и чистых URL, но требует настройки сервера.

Проблемы с асинхронными обработчиками

Navigo не дожидается завершения асинхронного кода по умолчанию, что может привести к гонке данных:

router.on('/data', async () => {
  const response = await fetch('/api/data');
  const json = await response.json();
  console.log(json);
});

Если сразу после router.navigate('/data') выполняется другой код, данные могут быть еще не загружены.

Решение: использовать промисы или async/await корректно и учитывать состояния загрузки:

router.on('/data', async () => {
  try {
    const response = await fetch('/api/data');
    const json = await response.json();
    renderData(json);
  } catch (error) {
    console.error('Ошибка загрузки данных', error);
  }
});

Ключевые моменты:

  • Всегда обрабатывать ошибки сетевых запросов.
  • Не полагаться на синхронное выполнение после router.navigate.

Проблемы с навигацией без перезагрузки страницы

Иногда ссылки <a> ведут на новые страницы, игнорируя Navigo, если не перехватывать событие click:

<a href="/about">О нас</a>

Решение: использовать событие click для вызова router.navigate:

document.querySelectorAll('a').forEach(link => {
  link.addEventListener('click', (e) => {
    e.preventDefault();
    router.navigate(link.getAttribute('href'));
  });
});

Ключевые моменты:

  • e.preventDefault() предотвращает стандартную навигацию.
  • Все внутренние ссылки SPA должны работать через router.navigate().

Эти решения покрывают большинство типичных ошибок при работе с Navigo, включая инициализацию, конфликты маршрутов, работу с параметрами и асинхронный код, а также вопросы интеграции с History API и hash-mode. Правильная структура маршрутов и контроль переходов позволяют строить стабильные и предсказуемые одностраничные приложения.