SvelteKit load функции

В SvelteKit load функции являются ключевым инструментом для получения данных и подготовки их перед рендерингом страницы. Они позволяют централизованно обрабатывать запросы к серверу, взаимодействовать с API и передавать данные компонентам. Основная цель load функций — обеспечить синхронный или асинхронный поток данных для страницы или маршрута до того, как компонент будет отрисован.

load функции могут быть определены в следующих контекстах:

  • Страницы (+page.js / +page.ts) — вызываются при переходе на конкретный маршрут.
  • Серверные маршруты (+page.server.js / +page.server.ts) — выполняются исключительно на сервере.
  • Layout (+layout.js / +layout.server.js) — применяются к группе страниц, объединённых одним layout.

Сигнатура и структура load функции

Функция load принимает один объект с ключевыми параметрами:

export async function load({ params, url, fetch, session, stuff }) {
    // логика получения данных
    return {
        props: {
            data: ...
        },
        status: 200,
        error: null
    };
}
  • params — объект с параметрами маршрута, например, для /posts/[id] будет доступно { id: '...' }.
  • url — объект URL, предоставляющий доступ к query-параметрам и хосту.
  • fetch — функция для выполнения запросов к API с учётом того, что она поддерживает SSR (Server-Side Rendering).
  • session — объект сессии, если настроена соответствующая логика.
  • stuff — объект, позволяющий передавать данные между layout и page load функциями.

Возвращаемое значение функции load может содержать:

  • props — объект с данными для передачи компоненту.
  • status — HTTP-статус, используется при серверных ошибках.
  • error — объект ошибки или сообщение при неудачном выполнении запроса.
  • redirect — URL для перенаправления на другой маршрут.

Разграничение клиентских и серверных load функций

SvelteKit разделяет load функции на клиентские и серверные:

  1. Клиентские (+page.js)

    • Выполняются как на сервере при первой загрузке, так и на клиенте при навигации.
    • Могут обращаться к любым публичным API, но данные не защищены.
    • Используют fetch для запросов, автоматически инкапсулируя cookies и headers текущей сессии.
  2. Серверные (+page.server.js)

    • Выполняются только на сервере, что позволяет скрывать секретные ключи и токены.
    • Могут обращаться к базам данных, внутренним сервисам и приватным API.
    • Не вызываются при навигации на клиенте, что снижает нагрузку на фронтенд.

Пример серверного load для получения данных из базы данных:

export async function load({ params, fetch }) {
    const res = await fetch(`/api/posts/${params.id}`);
    if (!res.ok) {
        return { status: res.status, error: new Error('Не удалось загрузить пост') };
    }
    const post = await res.json();
    return { props: { post } };
}

Асинхронная загрузка данных и обработка ошибок

load функции полностью поддерживают асинхронный код. Для корректной обработки ошибок и статусов используются комбинации throw error(status, message) и redirect(status, location).

import { error, redirect } from '@sveltejs/kit';

export async function load({ params, fetch }) {
    const res = await fetch(`/api/users/${params.id}`);
    
    if (res.status === 404) {
        throw error(404, 'Пользователь не найден');
    }

    if (res.status === 401) {
        throw redirect(302, '/login');
    }

    const user = await res.json();
    return { props: { user } };
}
  • throw error(status, message) — мгновенно прерывает загрузку и отображает страницу ошибки.
  • throw redirect(status, location) — выполняет перенаправление до рендеринга страницы.

Работа с stuff между layout и page

stuff используется для передачи промежуточных данных между layout и page load функциями. Например, данные аутентификации или глобальные настройки могут быть загружены один раз в layout и доступны в дочерних страницах.

// +layout.server.js
export async function load() {
    const settings = await getSiteSettings();
    return { stuff: { settings } };
}

// +page.js
export async function load({ stuff }) {
    return { props: { settings: stuff.settings } };
}

Практические советы по использованию load

  • Всегда использовать fetch из контекста load, чтобы SSR корректно обрабатывал запросы.
  • Разделять серверные и клиентские load для безопасности и оптимизации производительности.
  • Минимизировать количество асинхронных запросов в клиентских load, чтобы ускорить навигацию.
  • Использовать stuff для передачи неизменяемых данных между layout и page вместо дублирования.
  • Всегда обрабатывать ошибки через throw error() и редиректы через throw redirect() для прозрачной навигации и UX.

Итоговая структура файла +page.js с load функцией

import { error, redirect } from '@sveltejs/kit';

export async function load({ params, fetch, stuff }) {
    try {
        const res = await fetch(`/api/data/${params.id}`);
        if (!res.ok) throw error(res.status, 'Ошибка загрузки данных');

        const data = await res.json();
        return {
            props: {
                data,
                settings: stuff.settings
            }
        };
    } catch (err) {
        console.error(err);
        throw error(500, 'Внутренняя ошибка сервера');
    }
}

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