Routing
Routing berbasis file dengan parameter dinamis, catch-all routes, route groups, dan layouts.
Bosia menggunakan routing berbasis file. File-file di dalam src/routes/ dipetakan langsung ke URL.
Route Statis
src/routes/+page.svelte → /
src/routes/about/+page.svelte → /about
src/routes/blog/+page.svelte → /blogSetiap file +page.svelte menjadi halaman pada path direktorinya.
Route Dinamis
Bungkus nama direktori dalam tanda kurung siku untuk membuat segmen dinamis:
src/routes/blog/[slug]/+page.svelte → /blog/hello-world
/blog/my-post
/blog/anythingAkses nilai yang cocok melalui params:
// +page.server.ts
export async function load({ params }: LoadEvent) {
const post = await getPost(params.slug);
return { post };
}Catch-All Routes
Gunakan [...rest] untuk mencocokkan beberapa segmen path:
src/routes/all/[...catchall]/+page.svelte → /all/a
/all/a/b/c
/all/anything/hereparams.catchall berisi seluruh sub-path yang cocok (misalnya "a/b/c").
Route Groups
Direktori yang dibungkus dalam tanda kurung tidak terlihat di URL tetapi memungkinkan Anda berbagi layout:
src/routes/(public)/+layout.svelte ← layout bersama
src/routes/(public)/+page.svelte → /
src/routes/(public)/about/+page.svelte → /about
src/routes/(admin)/+layout.svelte ← layout berbeda
src/routes/(admin)/dashboard/+page.svelte → /dashboardGrup (public) dan (admin) tidak pernah muncul di URL. Mereka hanya mengontrol +layout.svelte mana yang membungkus halaman di dalamnya.
Prioritas Route
Ketika beberapa route bisa cocok dengan URL, Bosia menyelesaikannya secara berurutan:
- Pencocokan tepat — route statis seperti
/about - Segmen dinamis — route
[param] - Catch-all — route
[...rest]
Layouts
+layout.svelte membungkus semua halaman dan child layout di dalam direktorinya:
<!-- src/routes/+layout.svelte -->
<script lang="ts">
import "../app.css";
let { children, data } = $props();
</script>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<main>
{@render children()}
</main>Layout bersarang secara otomatis — layout root membungkus layout grup, yang membungkus layout halaman. Konten anak dirender di mana {@render children()} berada.
Data Layout
Pasangkan layout dengan +layout.server.ts untuk memuat data:
// src/routes/+layout.server.ts
import type { LoadEvent } from "bosia";
export async function load({ locals }: LoadEvent) {
return {
appName: "My App",
user: locals.user,
};
}Semua halaman dan layout anak dapat mengakses data ini melalui parent() di loader mereka sendiri.
Halaman Error
Buat +error.svelte untuk menangani error yang dilempar oleh loader:
<!-- src/routes/+error.svelte -->
<script lang="ts">
import type { ErrorProps } from "./$types";
let { error }: ErrorProps = $props();
</script>
<h1>{error.status}</h1><p>{error.message}</p>Halaman error menerima HttpError yang dilempar oleh error() di dalam loader. Tempatkan halaman error pada level route di mana Anda ingin menangkap error — halaman ini menangkap error dari semua route anak. Tipe ErrorProps dan PageError di-generate ke ./$types — tidak perlu mendeklarasikan tipe prop secara manual.
Opsi Halaman
Atur perilaku rendering per halaman dengan mengekspor flag dari +page.server.ts:
// src/routes/dashboard/+page.server.ts
export const ssr = false; // lewati server render, kirim shell + hydrate di client
export const csr = false; // lewati hydration client, hanya HTML server-rendered
export const prerender = true; // build ke HTML statis saat `bosia build`ssr = false— serverload()tetap berjalan dan hasilnya diinjeksi sebagai page data; client melakukan hydrate dan render. Cocok untuk halaman dengan dependensi khusus browser (window, chart, widget pihak ketiga) atau halaman auth-gated di mana SSR menambah latensi tanpa nilai SEO.csr = false— tidak ada JS untuk halaman ini. HTML statis saja.prerender = true— di-capture saat build. Untuk route dinamis, ekspor jugaentries()yang mengembalikan nilai param yang akan di-prerender.
ssr = false bersama csr = false tidak akan merender apapun dan otomatis di-override ke csr = true (dengan peringatan di mode dev). ssr = false bersama prerender = true bertentangan; route akan dilewati saat prerender.