# 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
```
---
## 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)