SvelteKit Load Data — Svelte

Load functions memungkinkan kamu fetch data sebelum halaman dirender. +page.js (Universal Load) // src/routes/blog/+page.js export async function load({ fetch…

Fungsi load adalah function yang kamu ekspor dari +page.js atau +page.server.js untuk menyiapkan data sebuah halaman sebelum halaman itu digambar. Objek yang dia kembalikan sampai di +page.svelte sebagai prop data. Bayangin dapur dan meja saji Warung Bu Sri. Sebelum piring diantar, dapur menyiapkan isinya, dan pelayan tinggal membawa piring yang sudah terisi. Ada yang boleh disiapkan di dapur maupun di meja, seperti es teh yang diaduk di depan pembeli. Tapi ada yang cuma boleh di dapur, karena resep rahasia dan kompornya ada di sana. Dapur itu server, meja itu browser, +page.js adalah yang boleh di dua tempat, dan +page.server.js adalah yang cuma di dapur.

🧪 Tebakan cepat: +page.js untuk /menu berisi console.log("load /menu jalan"). Pembeli membuka /menu dengan mengetik alamatnya. Pesan itu muncul di terminal server, di console browser, atau di dua-duanya? Jawabannya ada di bagian "Siapa menjalankan load, dan di mana".

load di +page.js

Data menu Warung Bu Sri disimpan di satu file, seolah-olah database:

// src/lib/menu.js: pura-pura database
export const semuaMenu = [
  { id: 1, nama: "Nasi Goreng", harga: 15000 },
  { id: 2, nama: "Mie Ayam", harga: 12000 },
  { id: 3, nama: "Es Teh", harga: 5000 },
]
// src/routes/menu/+page.js
import { semuaMenu } from "#lib/menu.js"

export function load() {
  return { menu: semuaMenu }
}
<!-- src/routes/menu/+page.svelte -->
<script>
  export let data
</script>

<h2>Menu</h2>
<ul>
  {#each data.menu as m (m.id)}
    <li><a href="/menu/{m.id}">{m.nama}</a></li>
  {/each}
</ul>

params dan error(404)

Untuk route dinamis [id], load menerima params, sama seperti page.params di pelajaran Routing:

// src/routes/menu/[id]/+page.server.js
import { error } from "@sveltejs/kit"
import { semuaMenu } from "#lib/menu.js"

export function load({ params }) {
  const menu = semuaMenu.find((m) => m.id === Number(params.id))
  if (!menu) error(404, "Menu tidak ditemukan")
  return { menu }
}
<!-- src/routes/menu/[id]/+page.svelte -->
<script>
  export let data
</script>

<h2>{data.menu.nama}</h2>
<p>Rp {data.menu.harga}</p>

Hasilnya dari SvelteKit yang berjalan sungguhan:

Alamat params.id Yang tampil
/menu/2 "2" Mie Ayam, Rp 12000
/menu/9 "9" 404, Menu tidak ditemukan

+error.svelte

Halaman error bawaannya polos: <h1>404</h1> lalu <p>Menu tidak ditemukan</p>. Untuk tampilan sendiri, buat +error.svelte:

<!-- src/routes/+error.svelte -->
<script>
  import { page } from "$app/state"
</script>

<h2>{page.status}</h2>
<p>{page.error.message}</p>
<a href="/menu">Kembali ke menu</a>

/menu/9 sekarang menampilkan header Warung Bu Sri dari layout, lalu 404, Menu tidak ditemukan, dan tautan kembali. Error yang gak dibuat dengan error(), misalnya bug di kodemu, tampil sebagai 500 dengan pesan Internal Error; pesan aslinya cuma muncul di terminal server, supaya detailnya gak bocor ke pembeli.

Siapa menjalankan load, dan di mana

Dicoba di browser dengan console.log di tiap load:

Kejadian +page.js +page.server.js
alamat diketik atau di-refresh jalan di server, lalu sekali lagi di browser jalan di server; hasilnya ikut di HTML
klik tautan dari halaman lain jalan di browser saja, tanpa request ke server browser meminta /menu/2/__data.json, load jalan di server

Saat alamat diketik, server menjalankan load dan mengirim HTML yang sudah lengkap. Lalu JavaScript SvelteKit di browser mengambil alih HTML itu supaya tombol dan tautannya hidup; proses ini disebut hydration. Untuk itu, +page.js dijalankan sekali lagi di browser. Jadi pesannya muncul di dua tempat: terminal dan console browser. Itu jawaban tebakannya.

Akibatnya:

Proyek baru: SvelteKit 3 dan Svelte 5

Proyek baru dari npx sv create memaksa runes, dan di sana export let data ditolak compiler: Cannot use export let in runes mode. Halamannya menulis let { data } = $props(); sisanya sama, termasuk data.menu dan page dari $app/state. Editor latihan meng-compile dengan Svelte 4, jadi latihannya memakai export let data.

Latihan: load sungguhan di app kecil

Editor latihan menjalankan beberapa file route sekaligus, masing-masing dimulai baris yang menyebut path-nya, misalnya // src/routes/artikel/[slug]/+page.js atau <!-- src/routes/+page.svelte -->. Editor lalu bekerja seperti SvelteKit kecil di browser: klik link pindah halaman tanpa reload, load dipanggil dengan params, url, dan route, dan error(404, ...) menampilkan halaman error (+error.svelte kalau ada, atau halaman bawaan SvelteKit). Baris abu-abu di atas pratinjau menunjukkan alamatnya.

// src/routes/artikel/[slug]/+page.js
import { error } from "@sveltejs/kit"

export function load({ params }) {
  const artikel = semuaArtikel[params.slug]

  if (!artikel) {
    error(404, "Artikel tidak ditemukan")
  }

  return artikel
}

Klik /artikel/halo-sveltekit dan <h1> jadi Halo SvelteKit. Klik /artikel/belum-ditulis dan halaman error tampil dengan 404 dan Artikel tidak ditemukan. Server-nya gak ada sungguhan: +page.server.js juga jalan di pratinjau.

⚠️ Jebakan yang sering ketemu

TL;DR: load diekspor dari +page.js atau +page.server.js, jalan sebelum halaman digambar, dan objek yang dikembalikannya sampai di +page.svelte sebagai data (export let data, atau let { data } = $props() di proyek runes). Route [id] menerima params.id sebagai string, jadi bandingkan dengan Number(params.id); error(404, "Menu tidak ditemukan") dari @sveltejs/kit menampilkan +error.svelte, yang membaca page.status dan page.error.message dari $app/state. +page.js jalan di server saat alamat dibuka langsung, sekali lagi di browser saat hydration, dan di browser saja saat pindah lewat tautan. +page.server.js cuma jalan di server (browser memintanya lewat __data.json), jadi tempat untuk database dan rahasia, dan hasilnya gak boleh berisi function. Latihannya: load({ params }) di src/routes/artikel/[slug]/+page.js yang mengembalikan artikelnya, atau error(404, "Artikel tidak ditemukan").

Yang akan kamu pelajari