# sveltekit > SvelteKit full-stack Svelte framework. Covers routing, load functions, form actions, and server-side rendering. Use when building SvelteKit applications. USE WHEN: user mentions "SvelteKit", "Svelte Kit", asks about "+page.svelte", "load functions", "form actions in SvelteKit", "SvelteKit routing", "use:enhance", "hooks.server.ts", "SvelteKit adapters" DO NOT USE FOR: Svelte without SvelteKit - use `frontend-svelte` instead; Next.js - use `nextjs-app-router` instead; Nuxt - use `nuxt3` instead; Remix - use `remix` instead - Author: mariepellegrino89 - Repository: claude-dev-suite/claude-dev-suite - Version: 20260206202537 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/claude-dev-suite/claude-dev-suite - Web: https://mule.run/skillshub/@@claude-dev-suite/claude-dev-suite~sveltekit:20260206202537 --- --- name: sveltekit description: | SvelteKit full-stack Svelte framework. Covers routing, load functions, form actions, and server-side rendering. Use when building SvelteKit applications. USE WHEN: user mentions "SvelteKit", "Svelte Kit", asks about "+page.svelte", "load functions", "form actions in SvelteKit", "SvelteKit routing", "use:enhance", "hooks.server.ts", "SvelteKit adapters" DO NOT USE FOR: Svelte without SvelteKit - use `frontend-svelte` instead; Next.js - use `nextjs-app-router` instead; Nuxt - use `nuxt3` instead; Remix - use `remix` instead allowed-tools: Read, Grep, Glob, Write, Edit --- # SvelteKit Core Knowledge > **Full Reference**: See [advanced.md](advanced.md) for WebSocket integration, Server-Sent Events, Socket.IO, hybrid form actions, room management, and streaming patterns. > **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `sveltekit` for comprehensive documentation. ## Route Structure ``` src/routes/ ├── +page.svelte → / (page UI) ├── +page.server.ts → / (server load/actions) ├── +layout.svelte → (shared layout) ├── users/ │ ├── +page.svelte → /users │ └── [id]/ │ └── +page.svelte → /users/:id ``` ## Key Concepts - `+page.svelte` → UI component - `+page.server.ts` → Server-only code - `+page.ts` → Universal (runs both) - `+layout` → Nested layouts - `+error.svelte` → Error pages --- ## Load Functions ```ts // +page.server.ts import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ params, fetch }) => { const user = await db.users.find(params.id); return { user }; }; ``` ```svelte

{data.user.name}

``` --- ## Form Actions ```ts // +page.server.ts import type { Actions } from './$types'; export const actions: Actions = { default: async ({ request }) => { const data = await request.formData(); await db.users.create({ name: data.get('name') }); return { success: true }; }, delete: async ({ params }) => { await db.users.delete(params.id); } }; ``` ```svelte
``` ### Form Validation with Zod ```typescript // src/routes/users/+page.server.ts import { fail } from '@sveltejs/kit'; import { z } from 'zod'; const UserSchema = z.object({ email: z.string().email('Invalid email'), name: z.string().min(2, 'Name too short'), }); export const actions = { create: async ({ request }) => { const formData = await request.formData(); const data = Object.fromEntries(formData); const result = UserSchema.safeParse(data); if (!result.success) { return fail(400, { errors: result.error.flatten().fieldErrors, data, }); } await createUser(result.data); return { success: true }; }, }; ``` ```svelte
{#if form?.errors?.email} {form.errors.email[0]} {/if}
``` --- ## Security Configuration ```typescript // svelte.config.js export default { kit: { csrf: { checkOrigin: true }, csp: { directives: { 'default-src': ['self'], 'script-src': ['self'], }, }, }, }; // src/hooks.server.ts import type { Handle } from '@sveltejs/kit'; export const handle: Handle = async ({ event, resolve }) => { const response = await resolve(event); response.headers.set('X-Frame-Options', 'DENY'); response.headers.set('X-Content-Type-Options', 'nosniff'); return response; }; ``` --- ## Authentication ```typescript // src/hooks.server.ts import type { Handle } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit'; export const handle: Handle = async ({ event, resolve }) => { const session = event.cookies.get('session'); if (session) { event.locals.user = await verifySession(session); } // Protect routes if (event.url.pathname.startsWith('/admin')) { if (!event.locals.user?.isAdmin) { throw redirect(303, '/login'); } } return resolve(event); }; ``` --- ## Error Handling ```svelte

{$page.status}

{$page.error?.message}

Go home
``` ```typescript // src/hooks.server.ts import type { HandleServerError } from '@sveltejs/kit'; export const handleError: HandleServerError = async ({ error, event }) => { const errorId = crypto.randomUUID(); console.error('Server error:', { errorId, error, url: event.url }); return { message: 'An unexpected error occurred', errorId, }; }; ``` --- ## Performance ```typescript // Prerendering export const prerender = true; export const entries = async () => { const posts = await getPosts(); return posts.map((post) => ({ slug: post.slug })); }; // Streaming export const load: PageServerLoad = async () => { return { critical: await getCriticalData(), streamed: { slow: getSlowData(), // Not awaited }, }; }; ``` ```svelte {#await data.streamed.slow} {:then slowData} {/await} ``` --- ## When NOT to Use This Skill - **Svelte without SvelteKit**: Use `frontend-svelte` skill - **Next.js**: Use `nextjs-app-router` skill - **Nuxt**: Use `nuxt3` skill - **Remix**: Use `remix` skill ## Anti-Patterns | Anti-Pattern | Why It's Wrong | Correct Approach | |--------------|----------------|------------------| | Fetching in onMount | Client-side only, no SSR | Use load function | | Using +page.ts for secrets | Exposed to client | Use +page.server.ts | | Not using use:enhance | No progressive enhancement | Add use:enhance to forms | | Ignoring form validation | Security risk | Validate with Zod | | No +error.svelte | Poor error UX | Create error page | | Not setting CSRF protection | Security vulnerability | Enable csrf.checkOrigin | ## Quick Troubleshooting | Issue | Possible Cause | Solution | |-------|----------------|----------| | "Cannot access event.locals.user" | Not set in hooks | Set in handle hook | | Form action not triggered | Missing action attribute | Use action="?/actionName" | | Data undefined in load | Not exported | Export const load | | CSRF error | checkOrigin enabled | Check csrf settings | | Hydration error | Server/client differ | Use browser check | | Redirect doesn't work | Wrong status code | Use redirect(303, '/path') | ## Production Checklist - [ ] CSP headers configured - [ ] CSRF protection enabled - [ ] Error handling (+error.svelte, hooks) - [ ] Auth in hooks.server.ts - [ ] Form validation with Zod - [ ] use:enhance for progressive forms - [ ] Prerendering static routes - [ ] Streaming for slow data ## Reference Documentation - [Route Structure](quick-ref/route-structure.md) - [Load Functions](quick-ref/load-functions.md)