Навигация и меню

Навигация в SvelteKit строится вокруг встроенного роутинга, который базируется на файловой структуре проекта. Любой файл .svelte в папке src/routes автоматически становится маршрутом. Например, файл src/routes/about.svelte соответствует пути /about.

Ключевые моменты роутинга:

  • Динамические маршруты создаются с помощью квадратных скобок: [id].svelte соответствует /123, /abc и т.д.
  • Можно использовать вложенные маршруты: папка blog с файлом [slug].svelte даст путь /blog/my-post.
  • Файлы +layout.svelte и +layout.ts позволяют создавать общую структуру и обрабатывать навигацию для группы страниц.

Для навигации между страницами SvelteKit предоставляет встроенный <a> с атрибутом href, но для SPA-подобного поведения рекомендуется использовать sveltekit:prefetch и sveltekit:noscroll.

Примеры использования:

<a href="/about" sveltekit:prefetch>О нас</a>
  • sveltekit:prefetch — загружает страницу заранее при наведении.
  • sveltekit:noscroll — предотвращает прокрутку страницы вверх при переходе.
  • replaceState позволяет заменить текущую запись в истории браузера без создания новой.

Для программной навигации используется хук goto из @sveltejs/kit/navigation:

import { goto } from '$app/navigation';

goto('/dashboard');

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

Меню и боковые панели

UI-библиотеки для SvelteKit, такие как Svelte Material UI, Skeleton UI, Flowbite Svelte, предоставляют готовые компоненты меню и навигационных панелей.

Структура меню обычно включает:

  • Навигационный контейнер<nav> или компонент Drawer.
  • Список ссылок<ul> или List с элементами ListItem.
  • Подменю и выпадающие списки — часто реализуются через компоненты Menu или Dropdown.

Пример боковой панели с Skeleton UI:

<script>
  import { Drawer, List, ListItem } from '@skeletonlabs/skeleton';
</script>

<Drawer open={true}>
  <List>
    <ListItem><a href="/">Главная</a></ListItem>
    <ListItem><a href="/about">О нас</a></ListItem>
    <ListItem><a href="/contact">Контакты</a></ListItem>
  </List>
</Drawer>

Особенности работы с выпадающими меню:

  • Menu поддерживает вложенные элементы с MenuItem и MenuGroup.
  • Состояние открыто/закрыто часто управляется через bind:open.
  • Анимации перехода реализуются через встроенные transition-эффекты Svelte (slide, fade).

Навигация с авторизацией

Для защищённых маршрутов используется комбинация layout-файлов и load функций:

// +layout.ts
import { redirect } from '@sveltejs/kit';

export async function load({ session }) {
  if (!session.user) {
    throw redirect(302, '/login');
  }
}

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

{#if user.isLoggedIn}
  <ListItem><a href="/dashboard">Панель</a></ListItem>
{:else}
  <ListItem><a href="/login">Вход</a></ListItem>
{/if}

Адаптивная навигация

Для мобильных устройств боковые панели и выпадающие меню часто скрываются за кнопкой-гамбургером:

<script>
  import { Drawer } from '@skeletonlabs/skeleton';
  let open = false;
</script>

<button on:click={() => open = !open}>Меню</button>
<Drawer bind:open>
  <List>
    <ListItem><a href="/">Главная</a></ListItem>
    <ListItem><a href="/about">О нас</a></ListItem>
  </List>
</Drawer>

Рекомендации по UX:

  • Всегда обеспечивать возможность закрытия меню кликом вне него.
  • Поддерживать клавиатурную навигацию (ArrowUp/ArrowDown для выпадающих списков).
  • Для больших приложений использовать динамическую генерацию меню из массива объектов, что упрощает поддержку и локализацию.

Интеграция с внешними UI-библиотеками

SvelteKit UI-библиотеки позволяют ускорить разработку, предоставляя готовые стили и компоненты:

  • Svelte Material UI — компоненты Material Design, поддержка Drawer, Menu, AppBar.
  • Flowbite Svelte — Tailwind-базированные компоненты с поддержкой модальных окон, Dropdown, Navbar.
  • Skeleton UI — лёгкая библиотека с Drawer, List, Menu, оптимизированная под производительность.

Каждая библиотека обычно требует обёртку для глобальных стилей и может потребовать конфигурации для SSR, так как SvelteKit рендерит страницы на сервере.

Поддержка состояния активного маршрута

Активный пункт меню можно подсвечивать через реактивные переменные, используя $page.url.pathname:

<script>
  import { page } from '$app/stores';
</script>

<ListItem class:active={$page.url.pathname === '/about'}>
  <a href="/about">О нас</a>
</ListItem>

<style>
  .active a {
    font-weight: bold;
    color: #1e40af;
  }
</style>

Это обеспечивает пользователю визуальное понимание текущего положения в приложении и повышает удобство навигации.

Lazy-loading и префетч

Для больших приложений важно минимизировать нагрузку на начальную загрузку. В SvelteKit это достигается через:

  • sveltekit:prefetch для ссылок.
  • Динамический импорт компонентов внутри меню:
<script>
  let LazyComponent;
  async function loadComponent() {
    const module = await import('./HeavyMenu.svelte');
    LazyComponent = module.default;
  }
</script>

<button on:click={loadComponent}>Показать меню</button>
{#if LazyComponent}
  <svelte:component this={LazyComponent}/>
{/if}

Такой подход позволяет улучшить производительность и отзывчивость интерфейса.


Эти принципы создают прочную основу для построения продвинутой и гибкой навигации в приложениях на SvelteKit с использованием современных UI-библиотек.