Перейти к содержимому

Параметры страницы

По умолчанию SvelteKit сначала отрисовывает (или пререндерит) любой компонент на сервере и отправляет его клиенту в виде HTML. Затем компонент снова отрисовывается в браузере для обеспечения интерактивности в процессе, называемом гидратацией. Поэтому важно, чтобы компоненты могли работать в обоих окружениях. После этого SvelteKit инициализирует роутер, который обрабатывает последующие переходы.

Вы можете управлять этими параметрами для каждой страницы, экспортируя настройки из +page.js или +page.server.js, либо для групп страниц через общие +layout.js или +layout.server.js. Для настройки всего приложения экспортируйте параметры из корневого макета. Дочерние макеты и страницы переопределяют значения, установленные в родительских макетах. Например, можно включить пререндеринг для всего приложения, но отключить его для динамических страниц.

Эти настройки можно комбинировать в разных частях приложения. Например:

  • Пререндерить маркетинговые страницы для максимальной скорости
  • Использовать серверный рендеринг для динамических страниц (SEO и доступность)
  • Сделать админ-панель SPA с клиентским рендерингом

Это делает SvelteKit чрезвычайно гибким.

Многие маршруты приложения могут быть представлены как статические HTML-файлы, сгенерированные при сборке. Такие маршруты можно пререндерить.

+page.js/+page.server.js/+server.js
export const prerender = true;

Альтернативно, вы можете установить export const prerender = true в корневом +layout.js или +layout.server.js, чтобы пререндерить всё, кроме страниц, явно помеченных как не подлежащие пререндерингу:

+page.js/+page.server.js/+server.js
export const prerender = false;

Маршруты с prerender = true исключаются из манифестов, используемых для динамического SSR, что уменьшает размер вашего сервера (или serverless/edge функций). В некоторых случаях может потребоваться пререндерить маршрут, но также включить его в манифест (например, для маршрута типа /blog/[slug], где вы хотите пререндерить самый популярный контент, но рендерить на сервере остальное) — для таких случаев есть третий вариант ‘auto’:

+page.js/+page.server.js/+server.js
export const prerender = 'auto';

Пререндерер начинает с корня приложения и генерирует файлы для всех страниц и маршрутов +server.js, помеченных для пререндеринга. Каждая страница сканируется на наличие <a>-элементов, ссылающихся на другие страницы, которые также могут быть пререндерены. Обычно не требуется указывать, какие страницы должны быть обработаны. Если это необходимо, используйте config.kit.prerender.entries или экспортируйте функцию entries из динамического маршрута.

Во время пререндеринга значение building, импортированное из $app/environment, будет true.

В отличие от других параметров страниц, prerender также применяется к файлам +server.js. Эти файлы не зависят от макетов, но наследуют значения по умолчанию от страниц, которые запрашивают их данные. Например, если +page.js содержит такую функцию load

+page.js
export const prerender = true;
/** @type {import('./$types').PageLoad} */
export async function load({ fetch }) {
const res = await fetch('/my-server-route.json');
return await res.json();
}

…то src/routes/my-server-route.json/+server.js будет рассматриваться как пререндерируемый, если сам не содержит export const prerender = false.

Когда не следует использовать пререндеринг

Заголовок раздела «Когда не следует использовать пререндеринг»

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

Примечание: можно пререндерить страницы, загружающие данные на основе параметров (например, src/routes/blog/[slug]/+page.svelte).

Использование url.searchParams при пререндеринге запрещено. Если нужно его использовать, делайте это только в браузере (например, в onMount).

Страницы с действиями нельзя пререндерить, так как сервер должен обрабатывать POST-запросы.

Пререндеринг записывает файлы, поэтому невозможно иметь два эндпойнта, создающих файл и директорию с одинаковым именем. Например, src/routes/foo/+server.js и src/routes/foo/bar/+server.js попытаются создать foo и foo/bar, что невозможно.

Рекомендуется всегда указывать расширение файла: src/routes/foo.json/+server.js и src/routes/foo/bar.json/+server.js создадут foo.json и foo/bar.json, которые могут сосуществовать.

Для страниц эта проблема решается созданием foo/index.html вместо foo.

Если вы столкнулись с ошибкой “The following routes were marked as prerenderable, but were not prerendered”, это означает, что маршрут (или родительский макет для страницы) имеет export const prerender = true, но не был обнаружен краулером пререндеринга.

Поскольку такие маршруты не могут быть отрендерены сервером динамически, это вызовет ошибки при попытке доступа. Способы решения:

  1. Убедитесь, что SvelteKit может найти маршрут:
  • Добавьте ссылки в config.kit.prerender.entries
  • Используйте опцию entries для динамических маршрутов (с [параметрами])
  • Непререндеряемые страницы игнорируются, даже если ссылаются на пререндеряемые
  1. Проверьте ссылки между страницами:
  • SvelteKit должен находить маршруты через ссылки с других пререндеренных страниц
  1. Измените настройку:
  • Замените export const prerender = true на export const prerender = 'auto'
  • Маршруты с 'auto' могут рендериться сервером динамически

SvelteKit автоматически находит страницы для пререндеринга, начиная с точек входа. По умолчанию все нединамические маршруты считаются точками входа. Например, для таких маршрутов:

Окно терминала
/ # нединамический
/blog # нединамический
/blog/[slug] # динамический (из-за `[slug]`)

SvelteKit пререндерит / и /blog, обнаруживая ссылки типа <a href="/blog/hello-world"> для новых страниц.

Если ссылки на страницы вроде /blog/hello-world отсутствуют (или не на пререндеренных страницах), нужно явно указать их существование через:

  • config.kit.prerender.entries
  • Экспорт функции entries из +page.js, +page.server.js или +server.js динамического маршрута:
src/routes/blog/[slug]/+page.server.js
/** @type {import('./$types').EntryGenerator} */
export function entries() {
return [
{ slug: 'hello-world' },
{ slug: 'another-blog-post' }
];
}
export const prerender = true;

Функция entries может быть асинхронной, что позволяет (например) получить список постов из CMS или базы данных, как в примере выше.

По умолчанию SvelteKit сначала рендерит страницу на сервере и отправляет HTML клиенту для гидратации. Если установить ssr в false, вместо этого будет отправлена пустая «оболочка» страницы. Это полезно, если страницу нельзя отрендерить на сервере (например, из-за использования браузерных глобальных объектов вроде document), но в большинстве случаев не рекомендуется (см. приложение).

+page.js
export const ssr = false;
// Если и `ssr`, и `csr` установлены в `false`, ничего не будет отрендерено!

Если добавить export const ssr = false в корневой +layout.js, всё приложение будет рендериться только на клиенте — по сути, превращая его в SPA.

Обычно SvelteKit гидратирует серверно-рендеренный HTML в интерактивную клиентскую страницу (CSR). Некоторым страницам JavaScript вообще не нужен — например, многим блогам и страницам «о нас». В таких случаях можно отключить CSR:

+page.js
export const csr = false;
// Если и `csr`, и `ssr` установлены в `false`, ничего не будет отрендерено!

Отключение CSR исключает отправку JavaScript на клиент. Это означает:

  • Страница должна работать только на HTML и CSS
  • Теги <script> внутри компонентов Svelte удаляются
  • Элементы <form> нельзя прогрессивно улучшать
  • Переходы по ссылкам обрабатываются браузером с полной перезагрузкой страницы
  • Hot Module Replacement (HMR) отключается

Для включения csr в режиме разработки (например, для использования HMR) можно сделать так:

+page.js
import { dev } from '$app/environment';
export const csr = dev;

По умолчанию SvelteKit удаляет завершающие слеши из URL — при посещении /about/ будет выполнен редирект на /about. Это поведение можно изменить с помощью опции trailingSlash, которая принимает значения:

  • 'never' (по умолчанию)
  • 'always'
  • 'ignore'

Как и с другими настройками страниц, это значение можно экспортировать из +layout.js или +layout.server.js, и оно будет применено ко всем дочерним страницам. Также конфигурацию можно экспортировать из файлов +server.js.

src/routes/+layout.js
export const trailingSlash = 'always';

Эта опция также влияет на пререндеринг. При trailingSlash: 'always' маршрут /about создаст файл about/index.html, в противном случае — about.html, следуя соглашениям статических веб-серверов.

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

config — это объект с парами ключ-значение верхнего уровня. Конкретная структура зависит от используемого адаптера. Каждый адаптер должен предоставлять интерфейс Config для типизации. Подробности см. в документации вашего адаптера.

src/routes/+page.js
/** @type {import('some-adapter').Config} */
export const config = {
runtime: 'edge'
};

Объекты config объединяются на верхнем уровне (но не на вложенных уровнях). Это означает, что вам не нужно повторять все значения в +page.js, если вы хотите переопределить только некоторые значения из родительского +layout.js. Например, такая конфигурация в макете…

src/routes/+layout.js
export const config = {
runtime: 'edge',
regions: 'all',
foo: {
bar: true
}
}

…переопределяется такой конфигурацией страницы…

src/routes/+page.js
export const config = {
regions: ['us1', 'us2'],
foo: {
baz: true
}
}

…что даёт итоговое значение конфига { runtime: 'edge', regions: ['us1', 'us2'], foo: { baz: true } } для этой страницы.