Фреймворки дают клиентский роутинг из коробки. У HTML и Web Components его нет. Если сайт уже отдаёт полные страницы, а клиентская навигация нужна только для части разделов, переписывать всё на фреймворк незачем.
Такая задача возникает в нескольких случаях. На существующем сайте два-три раздела должны переключаться без полной перезагрузки, а остальное по-прежнему жить как обычные HTML-страницы. В отдельном микрофронтенде или встраиваемом разделе не хочется добавлять фреймворк только ради навигации. При постепенном рефакторинге прямые URL должны оставаться полноценными страницами: для SEO, для первого экрана и на случай, если JavaScript не загрузился.
Эту задачу можно решить напрямую через History API, но тогда загрузку HTML, извлечение нужного фрагмента, вложенные макеты и сохранение обычных переходов при отключённом JavaScript придётся предусмотреть самостоятельно. Можно взять мини-роутер с конфигурацией в JavaScript и собственным деревом представлений — это удобно, когда маршруты и представления уже описываются в JavaScript.
Если исходной точкой должен оставаться HTML, который отдаёт сервер, можно использовать Aura Router: маршруты объявляются как Custom Elements, а ссылки остаются обычными <a href>. Без JavaScript те же URL открываются как обычные страницы.
Сделаем сайт из двух страниц. В пустой папке проекта выполните:
npm init -y
npm install --save-exact @auraui/router@0.1.0
npm install --save-dev vite
index.html:
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home</title>
<script type="module" src="/src/main.js"></script>
</head>
<body>
<nav>
<a href="/" aura-router-link>Home</a>
<a href="/about/" aura-router-link>About</a>
</nav>
<main id="content">
<h1>Home</h1>
<p>Это полная HTML-страница.</p>
</main>
<aura-outlet></aura-outlet>
<aura-router extract="#content">
<aura-route path="/" view="/"></aura-route>
<aura-route path="/about/" view="/about/"></aura-route>
</aura-router>
</body>
</html>
Ссылки остаются обычными. Атрибут aura-router-link говорит роутеру обработать клик клиентской навигацией, а не полной перезагрузкой страницы. Селектор extract="#content" указывает, какой фрагмент полной HTML-страницы вставлять в <aura-outlet>. При первой загрузке Aura подхватывает уже находящийся в документе #content и не запрашивает текущую страницу повторно. При переходах роутер загружает новую страницу и извлекает из неё фрагмент, соответствующий селектору #content.
Скопируйте index.html в about/index.html. Смените <title> на About и замените блок #content:
<main id="content">
<h1>About</h1>
<p>Прямой заход на этот URL тоже отдаёт полную страницу.</p>
</main>
Навигацию, <aura-outlet>, маршруты и скрипт оставьте теми же.
Создайте src/main.js:
import { AuraRouter } from "@auraui/router";
AuraRouter.install();
Это весь JavaScript.
Запуск:
npx vite
Откройте URL, который напечатает Vite, и проверьте три пункта:
-
Прямой заход на
/about/и перезагрузка страницы — отдаётся полная HTML-страница. -
Клики по Home и About — меняются URL и
#content, документ не перезагружается. -
Отключите JavaScript и пройдите те же ссылки — переходы станут обычными загрузками страниц, но страницы и ссылки продолжат работать.
Без npm тоже можно проверить. Если страницы уже отдаются по HTTP, вместо /src/main.js вставьте в обе страницы:
<script type="module">
import { AuraRouter } from "https://esm.sh/@auraui/router@0.1.0";
AuraRouter.install();
</script>
Для продакшена пакет лучше установить из npm и включить в сборку приложения.
Если общий интерфейс не должен размонтироваться при смене дочернего URL, вынесите его в родительский макет (layout):
<template id="workspace-shell">
<workspace-sidebar></workspace-sidebar>
<aura-outlet></aura-outlet>
</template>
<aura-route path="/workspace/" layout="workspace-shell">
<aura-route path="." view="/workspace/"></aura-route>
<aura-route path="settings" view="/workspace/settings/"></aura-route>
</aura-route>
Пока навигация остаётся внутри /workspace/, родительский макет остаётся смонтированным, меняется только вложенный <aura-outlet>. Прямой заход на вложенный URL должен вернуть родительский макет, вложенный <aura-outlet> и дочерний контент. Aura эту серверную разметку не генерирует.
В результате каждый URL остаётся полноценной HTML-страницей, а при включённом JavaScript переходы становятся клиентскими. Это базовая модель Aura Router; более сложные деревья маршрутов строятся по тому же принципу.
Текущий релиз — 0.1.0, публичный API ещё может измениться до 1.0. Поэтому лучше зафиксировать точную версию.
Примеры и дополнительные материалы:
-
демо — навигация в браузере;
-
StackBlitz — код статьи без локальной установки;
-
история появления Aura Router на DEV.to (на английском).
Автор: BELOYAR2025
