{"id":"e192fe03-06e3-4100-ac1a-c7cacc335724","shortId":"mPPuX5","kind":"skill","title":"sveltekit","tagline":"Build full-stack web applications with SvelteKit — file-based routing, SSR, SSG, API routes, and form actions in one framework.","description":"# SvelteKit Full-Stack Development\n\n## Overview\n\nSvelteKit is the official full-stack framework built on top of Svelte. It provides file-based routing, server-side rendering (SSR), static site generation (SSG), API routes, and progressive form actions — all with Svelte's compile-time reactivity model that ships zero runtime overhead to the browser. Use this skill when building fast, modern web apps where both DX and performance matter.\n\n## When to Use This Skill\n\n- Use when building a new full-stack web application with Svelte\n- Use when you need SSR or SSG with fine-grained control per route\n- Use when migrating a SPA to a framework with server capabilities\n- Use when working on a project that needs file-based routing and collocated API endpoints\n- Use when the user asks about `+page.svelte`, `+layout.svelte`, `load` functions, or form actions\n\n## How It Works\n\n### Step 1: Project Setup\n\n```bash\nnpm create svelte@latest my-app\ncd my-app\nnpm install\nnpm run dev\n```\n\nChoose **Skeleton project** + **TypeScript** + **ESLint/Prettier** when prompted.\n\nDirectory structure after scaffolding:\n\n```\nsrc/\n  routes/\n    +page.svelte        ← Root page component\n    +layout.svelte      ← Root layout (wraps all pages)\n    +error.svelte       ← Error boundary\n  lib/\n    server/             ← Server-only code (never bundled to client)\n    components/         ← Shared components\n  app.html              ← HTML shell\nstatic/                 ← Static assets\n```\n\n### Step 2: File-Based Routing\n\nEvery `+page.svelte` file in `src/routes/` maps directly to a URL:\n\n```\nsrc/routes/+page.svelte          → /\nsrc/routes/about/+page.svelte    → /about\nsrc/routes/blog/[slug]/+page.svelte  → /blog/:slug\nsrc/routes/shop/[...path]/+page.svelte → /shop/* (catch-all)\n```\n\n**Route groups** (no URL segment): wrap in `(group)/` folder.\n**Private routes** (not accessible as URLs): prefix with `_` or `(group)`.\n\n### Step 3: Loading Data with `load` Functions\n\nUse a `+page.ts` (universal) or `+page.server.ts` (server-only) file alongside the page:\n\n```typescript\n// src/routes/blog/[slug]/+page.server.ts\nimport { error } from '@sveltejs/kit';\nimport type { PageServerLoad } from './$types';\n\nexport const load: PageServerLoad = async ({ params, fetch }) => {\n  const post = await fetch(`/api/posts/${params.slug}`).then(r => r.json());\n\n  if (!post) {\n    error(404, 'Post not found');\n  }\n\n  return { post };\n};\n```\n\n```svelte\n<!-- src/routes/blog/[slug]/+page.svelte -->\n<script lang=\"ts\">\n  import type { PageData } from './$types';\n  export let data: PageData;\n</script>\n\n<h1>{data.post.title}</h1>\n<article>{@html data.post.content}</article>\n```\n\n### Step 4: API Routes (Server Endpoints)\n\nCreate `+server.ts` files for REST-style endpoints:\n\n```typescript\n// src/routes/api/posts/+server.ts\nimport { json } from '@sveltejs/kit';\nimport type { RequestHandler } from './$types';\n\nexport const GET: RequestHandler = async ({ url }) => {\n  const limit = Number(url.searchParams.get('limit') ?? 10);\n  const posts = await db.post.findMany({ take: limit });\n  return json(posts);\n};\n\nexport const POST: RequestHandler = async ({ request }) => {\n  const body = await request.json();\n  const post = await db.post.create({ data: body });\n  return json(post, { status: 201 });\n};\n```\n\n### Step 5: Form Actions\n\nForm actions are the SvelteKit-native way to handle mutations — no client-side fetch required:\n\n```typescript\n// src/routes/contact/+page.server.ts\nimport { fail, redirect } from '@sveltejs/kit';\nimport type { Actions } from './$types';\n\nexport const actions: Actions = {\n  default: async ({ request }) => {\n    const data = await request.formData();\n    const email = data.get('email');\n\n    if (!email) {\n      return fail(400, { email, missing: true });\n    }\n\n    await sendEmail(String(email));\n    redirect(303, '/thank-you');\n  }\n};\n```\n\n```svelte\n<!-- src/routes/contact/+page.svelte -->\n<script lang=\"ts\">\n  import { enhance } from '$app/forms';\n  import type { ActionData } from './$types';\n  export let form: ActionData;\n</script>\n\n<form method=\"POST\" use:enhance>\n  <input name=\"email\" type=\"email\" />\n  {#if form?.missing}<p class=\"error\">Email is required</p>{/if}\n  <button type=\"submit\">Subscribe</button>\n</form>\n```\n\n### Step 6: Layouts and Nested Routes\n\n```svelte\n<!-- src/routes/+layout.svelte -->\n<script lang=\"ts\">\n  import type { LayoutData } from './$types';\n  export let data: LayoutData;\n</script>\n\n<nav>\n  <a href=\"/\">Home</a>\n  <a href=\"/blog\">Blog</a>\n  {#if data.user}\n    <a href=\"/dashboard\">Dashboard</a>\n  {/if}\n</nav>\n\n<slot />  <!-- child page renders here -->\n```\n\n```typescript\n// src/routes/+layout.server.ts\nimport type { LayoutServerLoad } from './$types';\n\nexport const load: LayoutServerLoad = async ({ locals }) => {\n  return { user: locals.user ?? null };\n};\n```\n\n### Step 7: Rendering Modes\n\nControl per-route rendering with page options:\n\n```typescript\n// src/routes/docs/+page.ts\nexport const prerender = true;   // Static — generated at build time\nexport const ssr = true;         // Default — rendered on server per request\nexport const csr = false;        // Disable client-side hydration entirely\n```\n\n## Examples\n\n### Example 1: Protected Dashboard Route\n\n```typescript\n// src/routes/dashboard/+layout.server.ts\nimport { redirect } from '@sveltejs/kit';\nimport type { LayoutServerLoad } from './$types';\n\nexport const load: LayoutServerLoad = async ({ locals }) => {\n  if (!locals.user) {\n    redirect(303, '/login');\n  }\n  return { user: locals.user };\n};\n```\n\n### Example 2: Hooks — Session Middleware\n\n```typescript\n// src/hooks.server.ts\nimport type { Handle } from '@sveltejs/kit';\nimport { verifyToken } from '$lib/server/auth';\n\nexport const handle: Handle = async ({ event, resolve }) => {\n  const token = event.cookies.get('session');\n  if (token) {\n    event.locals.user = await verifyToken(token);\n  }\n  return resolve(event);\n};\n```\n\n### Example 3: Preloading and Invalidation\n\n```svelte\n<script lang=\"ts\">\n  import { invalidateAll } from '$app/navigation';\n\n  async function refresh() {\n    await invalidateAll(); // re-runs all load functions on the page\n  }\n</script>\n\n<button on:click={refresh}>Refresh</button>\n```\n\n## Best Practices\n\n- ✅ Use `+page.server.ts` for database/auth logic — it never ships to the client\n- ✅ Use `$lib/server/` for shared server-only modules (DB client, auth helpers)\n- ✅ Use form actions for mutations instead of client-side `fetch` — works without JS\n- ✅ Type all `load` return values with generated `$types` (`PageData`, `LayoutData`)\n- ✅ Use `event.locals` in hooks to pass server-side context to load functions\n- ❌ Don't import server-only code in `+page.svelte` or `+layout.svelte` directly\n- ❌ Don't store sensitive state in stores — use `locals` on the server\n- ❌ Don't skip `use:enhance` on forms — without it, forms lose progressive enhancement\n\n## Security & Safety Notes\n\n- All code in `+page.server.ts`, `+server.ts`, and `$lib/server/` runs exclusively on the server — safe for DB queries, secrets, and session validation.\n- Always validate and sanitize form data before database writes.\n- Use `error(403)` or `redirect(303)` from `@sveltejs/kit` rather than returning raw error objects.\n- Set `httpOnly: true` and `secure: true` on all auth cookies.\n- CSRF protection is built-in for form actions — do not disable `checkOrigin` in production.\n\n## Common Pitfalls\n\n- **Problem:** `Cannot use import statement in a module` in `+page.server.ts`\n  **Solution:** The file must be `.ts` or `.js`, not `.svelte`. Server files and Svelte components are separate.\n\n- **Problem:** Store value is `undefined` on first SSR render\n  **Solution:** Populate the store from the `load` function return value (`data` prop), not from client-side `onMount`.\n\n- **Problem:** Form action does not redirect after submit\n  **Solution:** Use `redirect(303, '/path')` from `@sveltejs/kit`, not a plain `return`. 303 is required for POST redirects.\n\n- **Problem:** `locals.user` is undefined inside a `+page.server.ts` load function\n  **Solution:** Set `event.locals.user` in `src/hooks.server.ts` before the `resolve()` call.\n\n## Related Skills\n\n- `@nextjs-app-router-patterns` — When you prefer React over Svelte for SSR/SSG\n- `@trpc-fullstack` — Add end-to-end type safety to SvelteKit API routes\n- `@auth-implementation-patterns` — Authentication patterns usable with SvelteKit hooks\n- `@tailwind-patterns` — Styling SvelteKit apps with Tailwind CSS\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["sveltekit","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity-skills"],"capabilities":["skill","source-sickn33","skill-sveltekit","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/sveltekit","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34460 github stars · SKILL.md body (8,763 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T06:51:57.276Z","embedding":null,"createdAt":"2026-04-18T21:45:40.837Z","updatedAt":"2026-04-22T06:51:57.276Z","lastSeenAt":"2026-04-22T06:51:57.276Z","tsv":"'/about':256 '/api/posts':332 '/blog':260 '/if':489,503 '/login':594 '/path':883 '/shop':265 '/thank-you':481 '1':171,568 '10':387 '2':237,599 '201':417 '3':289,635 '303':480,593,781,882,890 '4':351 '400':471 '403':778 '404':340 '5':419 '6':492 '7':523 'access':281 'action':20,63,166,421,423,449,454,455,672,808,873 'add':932 'alongsid':305 'alway':767 'api':16,58,152,352,941 'app':89,181,185,918,958 'app.html':230 'applic':7,110 'ask':158,995 'asset':235 'async':325,380,401,457,516,588,618 'auth':668,798,944 'auth-implementation-pattern':943 'authent':947 'await':330,390,405,409,461,475,628 'base':12,47,148,240 'bash':174 'best':645 'blog':499 'bodi':404,412 'boundari':216,1003 'browser':80 'build':2,85,103,544 'built':38,804 'built-in':803 'bundl':224 'button':640 'call':913 'cannot':818 'capabl':137 'catch':267 'catch-al':266 'cd':182 'checkorigin':812 'choos':191 'clarif':997 'clear':970 'click':642 'client':226,435,562,657,667,678,868 'client-sid':434,561,677,867 'code':222,713,748 'colloc':151 'common':815 'compil':69 'compile-tim':68 'compon':207,227,229,841 'const':322,328,377,382,388,398,403,407,453,459,463,513,538,547,557,585,615,621 'context':703 'control':124,526 'cooki':799 'creat':176,356 'criteria':1006 'csr':558 'csrf':800 'css':961 'dashboard':502,570 'data':291,411,460,772,863 'data.get':465 'data.post.content':349 'data.post.title':347 'data.user':501 'databas':774 'database/auth':650 'db':666,761 'db.post.create':410 'db.post.findmany':391 'default':456,550 'describ':974 'dev':190 'develop':28 'direct':248,718 'directori':198 'disabl':560,811 'dx':92 'email':464,466,468,472,478,486 'end':934,936 'end-to-end':933 'endpoint':153,355,363 'enhanc':735,743 'entir':565 'environ':986 'environment-specif':985 'error':215,313,339,777,788 'error.svelte':214 'eslint/prettier':195 'event':619,633 'event.cookies.get':623 'event.locals':695 'event.locals.user':627,907 'everi':242 'exampl':566,567,598,634 'exclus':755 'expert':991 'export':321,376,397,452,512,537,546,556,584,614 'fail':443,470 'fals':559 'fast':86 'fetch':327,331,437,680 'file':11,46,147,239,244,304,358,829,838 'file-bas':10,45,146,238 'fine':122 'fine-grain':121 'first':850 'folder':277 'form':19,62,165,420,422,484,671,737,740,771,807,872 'found':343 'framework':23,37,134 'full':4,26,35,107 'full-stack':3,25,34,106 'fullstack':931 'function':163,294,706,860,904 'generat':56,542,690 'get':378 'grain':123 'group':270,276,287 'handl':431,607,616,617 'helper':669 'home':498 'hook':600,697,952 'html':231,348 'httpon':791 'hydrat':564 'implement':945 'import':312,316,367,371,442,447,507,575,579,605,610,709,820 'input':1000 'insid':900 'instal':187 'instead':675 'invalid':638 'js':683,834 'json':368,395,414 'latest':178 'layout':210,493 'layout.server.ts':506,574 'layout.svelte':161,208,717 'layoutdata':693 'layoutserverload':509,515,581,587 'lib':217 'lib/server':659,753 'lib/server/auth':613 'limit':383,386,393,962 'load':162,290,293,323,514,586,686,705,859,903 'local':517,589,727 'locals.user':520,591,597,897 'logic':651 'lose':741 'map':247 'match':971 'matter':95 'middlewar':602 'migrat':129 'miss':473,485,1008 'mode':525 'model':72 'modern':87 'modul':665,824 'must':830 'mutat':432,674 'my-app':179,183 'nativ':428 'need':116,145 'nest':495 'never':223,653 'new':105 'nextj':917 'nextjs-app-router-pattern':916 'note':746 'npm':175,186,188 'null':521 'number':384 'object':789 'offici':33 'one':22 'onmount':870 'option':533 'output':980 'overhead':77 'overview':29 'page':206,213,307,532 'page.server.ts':300,311,441,648,750,826,902 'page.svelte':160,204,243,253,255,259,264,715 'page.ts':297,536 'pagedata':692 'pageserverload':318,324 'param':326 'params.slug':333 'pass':699 'path':263 'pattern':920,946,948,955 'per':125,528,554 'per-rout':527 'perform':94 'permiss':1001 'pitfal':816 'plain':888 'popul':854 'post':329,338,341,345,389,396,399,408,415,894 'practic':646 'prefer':923 'prefix':284 'preload':636 'prerend':539 'privat':278 'problem':817,844,871,896 'product':814 'progress':61,742 'project':143,172,193 'prompt':197 'prop':864 'protect':569,801 'provid':44 'queri':762 'r':335 'r.json':336 'rather':784 'raw':787 'react':924 'reactiv':71 'redirect':444,479,576,592,780,876,881,895 'refresh':643,644 'relat':914 'render':52,524,530,551,852 'request':402,458,555 'request.formdata':462 'request.json':406 'requesthandl':373,379,400 'requir':438,488,892,999 'resolv':620,632,912 'rest':361 'rest-styl':360 'return':344,394,413,469,518,595,631,687,786,861,889 'review':992 'root':205,209 'rout':13,17,48,59,126,149,203,241,269,279,353,496,529,571,942 'router':919 'run':189,754 'runtim':76 'safe':759 'safeti':745,938,1002 'sanit':770 'scaffold':201 'scope':973 'secret':763 'secur':744,794 'segment':273 'sendemail':476 'sensit':722 'separ':843 'server':50,136,218,220,302,354,553,663,701,711,730,758,837 'server-on':219,301,662,710 'server-sid':49,700 'server.ts':357,366,751 'session':601,624,765 'set':790,906 'setup':173 'share':228,661 'shell':232 'ship':74,654 'side':51,436,563,679,702,869 'site':55 'skeleton':192 'skill':83,100,915,965 'skill-sveltekit' 'skip':733 'slug':258,261,310 'solut':827,853,879,905 'source-sickn33' 'spa':131 'specif':987 'src':202 'src/hooks.server.ts':604,909 'src/routes':246,252,505 'src/routes/about':254 'src/routes/api/posts':365 'src/routes/blog':257,309 'src/routes/contact':440 'src/routes/dashboard':573 'src/routes/docs':535 'src/routes/shop':262 'ssg':15,57,119 'ssr':14,53,117,548,851 'ssr/ssg':928 'stack':5,27,36,108 'state':723 'statement':821 'static':54,233,234,541 'status':416 'step':170,236,288,350,418,491,522 'stop':993 'store':721,725,845,856 'string':477 'structur':199 'style':362,956 'submit':878 'subscrib':490 'substitut':983 'success':1005 'svelt':42,66,112,177,346,482,497,639,836,840,926 'sveltejs/kit':315,370,446,578,609,783,885 'sveltekit':1,9,24,30,427,940,951,957 'sveltekit-n':426 'tailwind':954,960 'tailwind-pattern':953 'take':392 'task':969 'test':989 'time':70,545 'token':622,626,630 'top':40 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'treat':978 'trpc':930 'trpc-fullstack':929 'true':474,540,549,792,795 'ts':832 'type':317,320,372,375,448,451,508,511,580,583,606,684,691,937 'typescript':194,308,364,439,504,534,572,603 'undefin':848,899 'univers':298 'url':251,272,283,381 'url.searchparams.get':385 'usabl':949 'use':81,98,101,113,127,138,154,295,647,658,670,694,726,734,776,819,880,963 'user':157,519,596 'valid':766,768,988 'valu':688,846,862 'verifytoken':611,629 'way':429 'web':6,88,109 'without':682,738 'work':140,169,681 'wrap':211,274 'write':775 'zero':75","prices":[{"id":"9a9b4e98-8ef2-4730-9840-6347803b0a22","listingId":"e192fe03-06e3-4100-ac1a-c7cacc335724","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:45:40.837Z"}],"sources":[{"listingId":"e192fe03-06e3-4100-ac1a-c7cacc335724","source":"github","sourceId":"sickn33/antigravity-awesome-skills/sveltekit","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/sveltekit","isPrimary":false,"firstSeenAt":"2026-04-18T21:45:40.837Z","lastSeenAt":"2026-04-22T06:51:57.276Z"}],"details":{"listingId":"e192fe03-06e3-4100-ac1a-c7cacc335724","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"sveltekit","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34460,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"62a6d18d8e8fb5e6a101f6d3dc4b17294f0bee36","skill_md_path":"skills/sveltekit/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/sveltekit"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"sveltekit","description":"Build full-stack web applications with SvelteKit — file-based routing, SSR, SSG, API routes, and form actions in one framework."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/sveltekit"},"updatedAt":"2026-04-22T06:51:57.276Z"}}