Sveltekit
SvelteKit - Full-stack Svelte framework with file-based routing, SSR/SSG, form actions, and adapters for deployment
- Skill ID
- bobmatnyc/claude-mpm-skills/sveltekit
- Publisher
- bobmatnyc
- Repository
- claude-mpm-skills
- Installs
- 0
- Files
- 2
- License
- MIT
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
bobmatnyc/claude-mpm-skills/sveltekitInstalls these files- SKILL.md
- metadata.json
What this skill tells the agent
SvelteKit - Full-Stack Svelte Framework
Overview
SvelteKit is the official full-stack framework for Svelte, providing file-based routing, server-side rendering (SSR), static site generation (SSG), form handling with progressive enhancement, and deployment adapters for any platform.
Key Features:
- File-based routing: Automatic routes from
src/routes/directory structure - Load functions: Type-safe data fetching (
+page.ts,+page.server.ts) - Form actions: Native form handling with progressive enhancement
- SSR/SSG/SPA: Flexible rendering modes with per-route control
- Adapters: Deploy to Vercel, Netlify, Node.js, Cloudflare, and more
- TypeScript-first: Generated types from
$typesfor type safety - Hooks: Middleware-like
handle,handleError,handleFetch - API routes:
+server.tsfiles for REST endpoints
Installation:
# Create new SvelteKit project
npm create svelte@latest my-app
cd my-app
npm install
npm run dev -- --open
# Templates: skeleton, demo app, library
# Choices: TypeScript, ESLint, Prettier, Playwright, VitestProject Structure
Standard SvelteKit Layout
my-sveltekit-app/
├── src/
│ ├── routes/ # File-based routing
│ │ ├── +page.svelte # / (home page)
│ │ ├── +page.ts # Universal load function
│ │ ├── +page.server.ts # Server-only load function
│ │ ├── +layout.svelte # Shared layout
│ │ ├── +layout.ts # Layout load function
│ │ ├── +error.svelte # Error page
│ │ ├── about/
│ │ │ └── +page.svelte # /about
│ │ ├── blog/
│ │ │ ├── +page.svelte # /blog (list)
│ │ │ ├── +page.server.ts # Load posts
│ │ │ └── [slug]/
│ │ │ ├── +page.svelte # /blog/my-post
│ │ │ └── +page.server.ts
│ │ └── api/
│ │ └── posts/
│ │ └── +server.ts # GET /api/posts
│ ├── lib/
│ │ ├── components/
│ │ ├── server/ # Server-only utilities
│ │ │ └── database.ts
│ │ ├── stores/
│ │ └── utils/
│ ├── hooks.server.ts # Server hooks
│ ├── hooks.client.ts # Client hooks
│ ├── app.html # HTML template
│ └── app.d.ts # TypeScript declarations
├── static/ # Static assets (robots.txt, favicon)
├── tests/ # Playwright tests
├── svelte.config.js # SvelteKit configuration
├── vite.config.ts # Vite configuration
└── package.jsonFile-Based Routing
Route Conventions
File naming determines routing:
| File | Route | Purpose |
|---|---|---|
+page.svelte | / | Page component |
+page.ts | - | Universal load (client + server) |
+page.server.ts | - | Server-only load |
+layout.svelte | - | Shared layout |
+layout.ts | - | Layout load |
+layout.server.ts | - | Server layout load |
+server.ts | /api/... | API endpoint (GET/POST/etc) |
+error.svelte | - | Error boundary |
Basic Routes
src/routes/
├── +page.svelte # / (home)
├── about/
│ └── +page.svelte # /about
├── contact/
│ └── +page.svelte # /contact
└── pricing/
└── +page.svelte # /pricingDynamic Routes
src/routes/
└── blog/
├── +page.svelte # /blog (list)
├── [slug]/
│ └── +page.svelte # /blog/my-post
└── [category]/
└── [slug]/
└── +page.svelte # /blog/tech/my-postAccess route params:
<!-- src/routes/blog/[slug]/+page.svelte -->
<script lang="ts">
import type { PageData } from './$types';
let { data } = $props<{ data: PageData }>();
</script>
<article>
<h1>{data.post.title}</h1>
<p>{data.post.content}</p>
</article>Optional Parameters
src/routes/
└── archive/
└── [[year]]/
└── [[month]]/
└── +page.svelte # /archive, /archive/2024, /archive/2024/11// src/routes/archive/[[year]]/[[month]]/+page.ts
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ params }) => {
const year = params.year || new Date().getFullYear();
const month = params.month || null;
return {
year,
month,
posts: await fetchPosts({ year, month })
};
};Rest Parameters
src/routes/
└── docs/
└── [...path]/
└── +page.svelte # /docs/guide/intro, /docs/api/reference// src/routes/docs/[...path]/+page.ts
export const load: PageLoad = async ({ params }) => {
const path = params.path; // "guide/intro"
const segments = path.split('/'); // ["guide", "intro"]
return {
doc: await fetchDoc(path)
};
};Load Functions
Universal Load (+page.ts)
Runs on both server and client. Must use fetch for data fetching.
// src/routes/products/+page.ts
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ fetch, params, url }) => {
const response = await fetch('/api/products');
const products = await response.json();
return {
products,
searchQuery: url.searchParams.get('q') || ''
};
};
// Prerendering options
export const prerender = true; // Static generation
export const ssr = false; // Disable SSR (SPA mode)
export const csr = true; // Enable client-side renderingServer-Only Load (+page.server.ts)
Runs only on server. Direct database access allowed.
// src/routes/dashboard/+page.server.ts
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import { db } from '$lib/server/database';
export const load: PageServerLoad = async ({ locals, cookies }) => {
// Check authentication
if (!locals.user) {
throw redirect(303, '/login');
}
// Direct database query (server-only)
const stats = await db.query.stats.findFirst({
where: eq(stats.userId, locals.user.id)
});
// Sensitive data stays on server
const apiKey = process.env.SECRET_API_KEY;
const data = await fetchPrivateData(apiKey);
return {
stats,
userData: data
};
};Streaming with Promises
// src/routes/posts/+page.server.ts
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async () => {
return {
// Immediate data
featured: await db.posts.findMany({ where: { featured: true } }),
// Streamed data (loads async)
recent: db.posts.findMany({ orderBy: { createdAt: 'desc' } }),
popular: db.posts.findMany({ orderBy: { views: 'desc' } })
};
};<!-- src/routes/posts/+page.svelte -->
<script lang="ts">
import type { PageData } from './$types';
let { data } = $props<{ data: PageData }>();
</script>
<h2>Featured</h2>
{#each data.featured as post}
<article>{post.title}</article>
{/each}
<h2>Recent</h2>
{#await data.recent}
<p>Loading recent posts...</p>
{:then posts}
{#each posts as post}
<article>{post.title}</article>
{/each}
{/await}
<h2>Popular</h2>
{#await data.popular}
<p>Loading popular posts...</p>
{:then posts}
{#each posts as post}
<article>{post.title}</article>
{/each}
{/await}Layouts
Shared Layout
<!-- src/routes/+layout.svelte -->
<script lang="ts">
import Header from '$lib/components/Header.svelte';
import Footer from '$lib/components/Footer.svelte';
import type { LayoutData } from './$types';
let { data, children } = $props<{ data: LayoutData, children: any }>();
</script>
<div class="app">
<Header user={data.user} />
<main>
{@render children()}
</main>
<Footer />
</div>
<style>
.app {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
</style>Layout Load
// src/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types';
More from bobmatnyc
Use this skill in a project
Open any RiverX project, search the Skills panel for bobmatnyc/claude-mpm-skills/sveltekit, and install it in one click.
