Svelte

SvelteKit: файловая маршрутизация

В приложении появляются страницы: главная, список товаров, карточка товара по id, профиль. Описывать каждый URL вручную в конфиге роутера значит держать карту маршрутов отдельно от файлов и синхронизировать их вручную. SvelteKit делает маршрут из самой структуры папок: каталог src/routes - это карта URL. Папка about даёт путь, файл +page.svelte в ней - саму страницу, а папка с именем в квадратных скобках вроде [id] - динамический сегмент. Структура на диске и есть роутер.

  • Главная страница: +page.svelte прямо в корне src/routes
  • Раздел блога: папка blog с +page.svelte для списка постов
  • Карточка поста по адресу: папка [slug] с +page.svelte для конкретной записи
  • Общая шапка и подвал на всех страницах через +layout.svelte в корне маршрутов
  • Переход между страницами по обычной ссылке a с клиентской навигацией без перезагрузки

Предварительные знания

  • Поднятый проект SvelteKit и запуск дев-сервера
  • Понимание URL как пути из сегментов, разделённых слешем
  • Компоненты Svelte: страница - это обычный компонент

Почему файловая маршрутизация

Идея выводить маршруты из структуры файлов появилась в фреймворках задолго до SvelteKit: ранние версии Next.js строили роуты из папки pages. SvelteKit, вышедший в стабильной версии 1.0 в декабре 2022, принял тот же принцип и развил его в систему специальных файлов с префиксом плюс: +page.svelte, +layout.svelte, +page.server.js. Префикс отделяет файлы фреймворка от обычных компонентов в той же папке. К версии 2 этот подход стал каноничным способом организации приложения на SvelteKit.

src/routes и +page.svelte

В SvelteKit маршрут - это путь внутри папки src/routes. Каждая вложенная папка добавляет сегмент к URL, а файл +page.svelte делает папку адресуемой страницей. Корневой +page.svelte отвечает за главную, папка about с +page.svelte - за путь к разделу about. Сам файл страницы - обычный компонент Svelte со всем, что в нём бывает: рунами, разметкой, стилями.

Файл about/+page.svelte автоматически становится страницей по пути к разделу about - никакой регистрации маршрута в конфиге не нужно. Внутри это полноценный компонент: здесь работают руны, события и стили. Чтобы добавить новую страницу, достаточно создать папку с файлом +page.svelte.

Префикс плюс отличает файлы маршрутизации от обычных. Только файлы вроде +page.svelte и +layout.svelte трактуются SvelteKit как часть роутера. Компонент без плюса в папке маршрута - просто переиспользуемый компонент, а не страница.

Что делает папку в src/routes адресуемой страницей?

+layout.svelte как общая обёртка

Шапка, навигация и подвал нужны на всех страницах, и дублировать их в каждом +page.svelte нерационально. Файл +layout.svelte задаёт обёртку для всех страниц своей папки и вложенных в неё папок. Лейаут получает контент текущей страницы через сниппет children и вставляет его в нужное место своего каркаса. Корневой лейаут оборачивает всё приложение.

Корневой +layout.svelte рисует навигацию и подвал, а на месте {@render children()} подставляется текущая страница. Это та же механика сниппета children, что у обычных компонентов-обёрток. Лейауты вкладываются: лейаут в папке blog оборачивает страницы блога внутри корневого лейаута, добавляя свой уровень оформления.

  • Дублирование каркаса — Шапка и подвал скопированы в каждый +page.svelte. Любая правка навигации означает изменение во всех страницах
  • Общий +layout.svelte — Каркас описан один раз, страницы вставляются через children. Навигация правится в одном месте для всего раздела

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

Какую роль выполняет файл +layout.svelte?

Динамические маршруты и навигация

Страниц вроде карточки товара или поста много, и заводить отдельную папку под каждый id нельзя. Динамический сегмент решает это: папка с именем в квадратных скобках, например [slug], сопоставляется с любым значением на этой позиции пути. Один файл blog/[slug]/+page.svelte обслуживает все посты, а конкретное значение сегмента доступно как параметр маршрута.

Папка [slug] ловит любое значение в этой позиции пути, поэтому путь к посту с одним slug и путь к посту с другим ведут на один и тот же файл страницы. Значение сегмента читается из page.params по имени папки. Переход между страницами делается обычной ссылкой a: SvelteKit перехватывает клик и навигирует на стороне клиента, без полной перезагрузки и повторной загрузки всего приложения.

Имя папкиТип маршрутаСопоставляется с
aboutСтатическийТолько путь /about
[id]ДинамическийЛюбым значением сегмента
[...rest]Перехват остаткаЛюбым числом сегментов

Имя папки динамического сегмента и есть имя параметра. Папка [slug] даёт параметр slug в page.params, папка [id] - параметр id. Если читать параметр под другим именем, чем у папки, значение будет пустым - имя должно совпадать.

Что создаёт папка с именем в квадратных скобках вроде [id] в src/routes?

Связь с другими темами

Маршрутизация - вход в серверную часть SvelteKit:

  • Настройка SvelteKit — Файловые маршруты работают внутри проекта SvelteKit
  • Компоненты — Страница и лейаут - обычные компоненты в специальных файлах
  • Функции load — Следующий шаг - загрузка данных для маршрута

Итог

  • Маршруты задаются структурой папки src/routes: дерево каталогов - это карта URL
  • Файл +page.svelte в папке делает её адресуемой страницей
  • Файл +layout.svelte оборачивает страницы своей папки и вложенных в общий каркас
  • Папка с именем в квадратных скобках вроде [id] создаёт динамический сегмент с параметром
  • Навигация по ссылке a идёт на стороне клиента без полной перезагрузки страницы

Связанные уроки

  • sv-02-setup-sveltekit — Файловая маршрутизация - часть SvelteKit, поэтому нужен поднятый проект SvelteKit
  • sv-03-components — Страница и лейаут - это обычные компоненты Svelte в специальных файлах маршрута
  • sv-19-load-functions — После структуры маршрутов следующий шаг - загрузка данных для страницы через load
SvelteKit: файловая маршрутизация

0

1

Войти