Navigasi
Navigasi programatik dan berbasis tautan di Bosia — goto(), beforeNavigate, afterNavigate, form actions, dan escape hatch full-reload.
Bosia menyediakan empat pola navigasi yang mencerminkan SvelteKit:
- Tautan
<a href>biasa — router mencegatnya. goto()— navigasi SPA programatik.- Form action
redirect(303, '/x')— navigasi pasca-submit yang digerakkan server. window.location.href— reload browser penuh (escape hatch).
Tiga yang pertama bersifat SPA — tidak mengeksekusi ulang skrip entry. Yang keempat membongkar dan menghidrasi ulang.
Tautan anchor
<a href="/dashboard">Dashboard</a>Handler klik milik Bosia mencegat klik anchor biasa dan menjalankan router.navigate(). Klik dengan modifier (Cmd, Ctrl, klik tengah) dan target="_blank" diteruskan ke browser, sehingga "buka di tab baru" tetap bekerja seperti yang diharapkan. rel="external" dan download juga ikut keluar.
`goto()`
import { goto } from "bosia/client";
await goto("/dashboard");
await goto("/login", { replaceState: true, invalidateAll: true });goto() mengembalikan sebuah Promise yang resolve setelah navigasi mengendap (loader berjalan, komponen ter-mount).
Opsi
| Opsi | Default | Deskripsi |
|---|---|---|
replaceState |
false |
Memakai history.replaceState alih-alih pushState. |
invalidateAll |
false |
Menandai setiap loader kotor agar tujuan menjalankan ulang semua server loader. |
noScroll |
false |
Melewati scroll-to-top default setelah navigasi. |
keepFocus |
false |
Dicadangkan — belum dihormati. |
state |
— | Dicadangkan — Bosia belum punya shallow routing. |
Jika URL cocok dengan route saat ini, goto() resolve langsung tanpa menjalankan ulang loader. Opsi invalidateAll: true tidak dihormati pada panggilan ke path yang sama — panggil invalidateAll() langsung (diimpor dari bosia/client) untuk menyegarkan di tempat.
Perilaku scroll
- Navigasi maju (link,
goto(), redirect form) scroll ke atas — atau ke elemen#hashjika URL tujuan memilikinya.goto(url, { noScroll: true })melewatinya untuk satu navigasi. - Back/forward (popstate) memulihkan posisi scroll halaman saat ditinggalkan. Router menyimpan posisi per entri history dan memulihkannya setelah halaman tujuan dirender, jadi listing panjang tidak melompat ke atas saat pengguna menekan Back. Posisi bertahan melewati reload via
sessionStorage.
Ini otomatis — tanpa kode aplikasi.
Snapshot
Scroll restoration mengembalikan posisi; snapshot mengembalikan state — isi form yang belum dikirim, accordion yang terbuka, kotak pencarian. Export objek snapshot dari +page.svelte:
<script lang="ts">
import type { Snapshot } from "./$types";
let comment = $state("");
export const snapshot: Snapshot<string> = {
capture: () => comment,
restore: (value) => (comment = value),
};
</script>
<textarea bind:value={comment}></textarea>capture() berjalan saat pengguna meninggalkan halaman; restore(value) berjalan saat mereka kembali via tombol Back/Forward browser. Snapshot juga bertahan melewati reload penuh — dipersist ke sessionStorage saat unload.
Aturan:
- Nilai yang di-capture harus bisa diserialisasi JSON (tanpa fungsi, Date jadi string) — begitulah cara ia bertahan melewati reload.
- Navigasi maju ke halaman tidak pernah me-restore — hanya Back/Forward (dan reload), sama seperti SvelteKit.
- Hanya
+page.svelteyang mendukungsnapshot(bukan layout).
Snapshot<T> juga bisa diimpor dari bosia/client.
Lifecycle hooks
beforeNavigate berjalan sebelum setiap navigasi sisi-klien. Callback boleh memanggil nav.cancel() untuk memblokir navigasi (kecuali pada back/forward browser — lihat di bawah).
<script lang="ts">
import { beforeNavigate, afterNavigate } from "bosia/client";
beforeNavigate((nav) => {
if (hasUnsavedChanges && !confirm("Discard changes?")) {
nav.cancel();
}
});
afterNavigate((nav) => {
console.log("navigated to", nav.to?.url.pathname);
});
</script>Keduanya otomatis tidak terdaftar lagi saat komponen pemanggil dihancurkan.
Objek Navigation
interface Navigation {
from: { url: URL; params: Record<string, string> } | null;
to: { url: URL; params: Record<string, string> } | null;
type: "link" | "goto" | "popstate" | "form" | "enter";
willUnload: boolean;
cancel: () => void;
}type— bagaimana navigasi dipicu.willUnload—truesaat browser akan membongkar halaman (tab ditutup, tautan eksternal). Untuk peristiwa inicancel()tidak berefek; gunakanaddEventListener("beforeunload", ...)langsung untuk meminta konfirmasi pengguna.cancel()pada navigasipopstate(back/forward) juga tidak berefek — browser sudah memindahkan pointer history-nya saat listener berjalan.
Indikator Loading
Bosia menampilkan bilah progres tipis di bagian atas halaman selama setiap navigasi klien. Untuk transisi yang lebih kaya, letakkan +loading.svelte di folder route dan Bosia merender kerangka itu secara otomatis saat tujuan dimuat — tertanam di dalam layout yang dibagi, tanpa perlu mengatur beforeNavigate. Lihat Kerangka Loading.
Form actions
Form action yang melempar redirect(303, "/x") bernavigasi melalui router secara otomatis saat dibungkus dengan use:enhance:
<form method="POST" action="?/logout" use:enhance>
<button>Log out</button>
</form>Lihat Form Actions untuk cerita lengkapnya.
`window.location.href` — reload penuh
Gunakan hanya saat Anda benar-benar perlu membongkar semua state klien (mis. logout, berganti tenant di aplikasi multi-tenant ketika konteks runtime yang segar diinginkan):
function hardLogout() {
document.cookie = "session=; Max-Age=0";
window.location.href = "/";
}Untuk navigasi internal, lebih baik goto() — lebih cepat (tanpa parse ulang skrip, tanpa biaya hidrasi ulang) dan mempertahankan cache loader sebisa mungkin.