Server Loaders
Muat data di server dengan load(), metadata(), dan pengaliran data parent().
Server loader berjalan pada setiap request untuk mengambil data bagi halaman dan layout.
Loader Halaman
Ekspor fungsi load dari +page.server.ts:
import type { LoadEvent } from "bosia";
export async function load({ params, url, locals, cookies }: LoadEvent) {
const post = await db.getPost(params.slug);
return { post };
}Objek yang dikembalikan menjadi prop data di +page.svelte:
<script lang="ts">
let { data } = $props();
</script>
<h1>{data.post.title}</h1><p>{data.post.content}</p>Loader Layout
+layout.server.ts bekerja dengan cara yang sama tetapi datanya tersedia untuk semua route anak:
// src/routes/+layout.server.ts
import type { LoadEvent } from "bosia";
export async function load({ locals }: LoadEvent) {
return {
appName: "Bosia Demo",
requestTime: locals.requestTime,
};
}Pengaliran Data dengan parent()
Loader anak dapat mengakses data dari loader layout induknya:
// src/routes/blog/[slug]/+page.server.ts
import type { LoadEvent } from "bosia";
export async function load({ params, parent }: LoadEvent) {
const parentData = await parent();
const post = await db.getPost(params.slug);
return {
post,
appName: parentData.appName, // from root layout loader
};
}Data mengalir dari atas ke bawah: layout root → layout grup → layout halaman → halaman.
Metadata
Ekspor fungsi metadata untuk mengatur judul halaman dan meta tag:
import type { MetadataEvent, LoadEvent } from "bosia";
export function metadata({ params }: MetadataEvent) {
const post = getPost(params.slug);
return {
title: `${post.title} — My Blog`,
description: `A blog post about ${params.slug}`,
meta: [{ property: "og:title", content: post.title }],
// Pass data to load() — avoids duplicate queries
data: { post },
};
}
export async function load({ params, parent, metadata }: LoadEvent) {
const parentData = await parent();
// Reuse data from metadata() — no duplicate DB query
const post = metadata?.post ?? getPost(params.slug);
return { post, appName: parentData.appName };
}Properti data pada nilai kembalian metadata() diteruskan ke load() sebagai event.metadata. Ini memungkinkan Anda mengambil data sekali dan berbagi di antara kedua fungsi.
Properti LoadEvent
| Properti | Tipe | Deskripsi |
|---|---|---|
url |
URL |
URL request |
params |
Record<string, string> |
Parameter route dinamis |
locals |
Record<string, any> |
Data yang disetel oleh middleware hooks |
cookies |
Cookies |
Membaca/menulis cookies |
fetch |
Function |
Fetch yang sadar sesi (meneruskan cookies) |
parent |
() => Promise<Record> |
Data dari loader layout induk |
metadata |
Record | null |
Data yang diteruskan dari fungsi metadata() |
Penanganan Error
Lempar error dari loader untuk menampilkan halaman error:
import { error, redirect } from "bosia";
export async function load({ params }: LoadEvent) {
const post = await db.getPost(params.slug);
if (!post) {
error(404, "Post not found");
}
if (post.isPrivate) {
redirect(303, "/login");
}
return { post };
}Deduplikasi Request
Request identik yang bersamaan berbagi satu loader in-flight secara default. Route per-user (apa pun yang membaca cookie atau sesi) wajib opt out dengan menempatkannya di bawah folder grup (private), atau Pengguna B akan menerima data Pengguna A.
Lihat Deduplikasi Request untuk model lengkap dan aturan keamanannya.
Timeout
Loader memiliki timeout yang dapat dikonfigurasi untuk mencegah response yang tergantung:
| Variabel Env | Default | Deskripsi |
|---|---|---|
LOAD_TIMEOUT |
— | Timeout untuk load() dalam ms |
METADATA_TIMEOUT |
— | Timeout untuk metadata() dalam ms |