Kurs Svelte i SvelteKit · Moduł 11: Routing w SvelteKit
Strony błędów i specjalne
W tej lekcji4
+error.svelte
<!-- src/routes/+error.svelte -->
<script>
import { page } from '$app/state';
</script>
<h1>Błąd {page.status}</h1>
<p>{page.error?.message}</p>
<a href="/">Wróć na stronę główną</a>Obiekt page z $app/state jest reaktywny i czytasz go bez znaku $. Dawny store $page z modułu $app/stores został w SvelteKit 3 usunięty.
Zgłaszanie błędów
// src/routes/warriors/[id]/+page.js
import { error } from '@sveltejs/kit';
export function load({ params }) {
const warrior = getWarrior(params.id);
if (!warrior) {
error(404, 'Wojownik nie znaleziony');
}
return { warrior };
}Funkcja error() sama rzuca wyjątek, więc nie piszesz przed nią throw (to zapis ze SvelteKit 1). Drugim argumentem jest zawsze tekst komunikatu.
+page.js vs +page.server.js
// +page.js - działa na serwerze I kliencie
export function load({ params, fetch }) {
// Może być wywołane podczas nawigacji client-side
return { data };
}// +page.server.js - TYLKO serwer
export function load({ params, locals }) {
// Dostęp do bazy danych, sekretów, itp.
return { data };
}Przekierowania
import { redirect } from '@sveltejs/kit';
export function load({ locals }) {
if (!locals.user) {
redirect(303, '/login');
}
return { user: locals.user };
}Tak samo jak error(), funkcja redirect() rzuca wyjątek sama - bez throw.
Kod do tej lekcji: App.svelte
<script>
// Nawigacja programowa i loading states
let loading = $state(false);
let currentPage = $state('home');
async function navigateTo(page) {
loading = true;
// Symulacja ładowania danych
await new Promise(r => setTimeout(r, 1000));
currentPage = page;
loading = false;
}
// Symulacja beforeNavigate
function handleBeforeNavigate(e, page) {
if (currentPage === 'form' && !confirm('Opuścić stronę?')) {
e.preventDefault();
return;
}
navigateTo(page);
}
</script>
<main class="navigation-demo">
<h1>Nawigacja SvelteKit</h1>
<nav class="nav">
<button onclick={(e) => handleBeforeNavigate(e, 'home')}>Home</button>
<button onclick={(e) => handleBeforeNavigate(e, 'warriors')}>Warriors</button>
<button onclick={(e) => handleBeforeNavigate(e, 'form')}>Form</button>
</nav>
{#if loading}
<div class="loading">
<div class="spinner"></div>
<p>Ładowanie...</p>
</div>
{:else}
<section class="content">
{#if currentPage === 'home'}
<h2>Strona główna</h2>
<p>Witaj w aplikacji!</p>
{:else if currentPage === 'warriors'}
<h2>Wojownicy</h2>
<p>Lista załadowana z serwera</p>
{:else if currentPage === 'form'}
<h2>Formularz</h2>
<p>Opuszczenie spowoduje utratę danych!</p>
<input placeholder="Wpisz coś..." />
{/if}
</section>
{/if}
<section class="code-example">
<h2>Programmatic navigation</h2>
<pre>
import {"{"} goto {"}"} from '$app/navigation';
// Prosta nawigacja
goto('/warriors');
// Z opcjami
goto('/warriors', {"{"}
replace: true,
refreshAll: true
{"}"});
</pre>
</section>
</main>
<style>
.navigation-demo {
font-family: 'Georgia', serif;
max-width: 600px;
margin: 0 auto;
padding: 2rem;
background: #0a1628;
color: #b8d4f7;
min-height: 100vh;
}
h1 {
color: #4a90d9;
text-align: center;
}
.nav {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-bottom: 2rem;
}
button {
padding: 0.75rem 1.5rem;
background: #1e3a5f;
color: #b8d4f7;
border: 1px solid #4a90d9;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #2a4a6f;
}
.loading {
text-align: center;
padding: 3rem;
}
.spinner {
width: 50px;
height: 50px;
border: 4px solid #1e3a5f;
border-top-color: #4a90d9;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 1rem;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
section {
background: rgba(74, 144, 217, 0.1);
border: 1px solid #4a90d9;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #4a90d9;
margin-top: 0;
}
input {
width: 100%;
padding: 0.75rem;
background: rgba(0,0,0,0.3);
border: 1px solid #4a90d9;
border-radius: 4px;
color: #b8d4f7;
margin-top: 0.5rem;
}
pre {
background: rgba(0,0,0,0.5);
padding: 1rem;
border-radius: 4px;
font-size: 0.85rem;
overflow-x: auto;
}
</style>Hasła z dokumentacji w tej lekcji
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jak zgłosić błąd 404 w funkcji load (SvelteKit 3)?