lunx.docs
DocsFrameworksSvelteKit

SvelteKit Adapter

Full-stack Svelte with file-based routing, SSR, SSG, server-side load functions, form actions, and adapter-based deployment. Verified with 25 routes and 302 auth redirects.

SvelteKit 2 · SSR · File Routing
File-based routing

+page.svelte files auto-generate routes. +layout.svelte wraps nested routes with shared UI.

SSR + SSG

Server-side rendering and static site generation per-route via the prerender option.

Server load functions

+page.server.ts load functions run on the server for data fetching before page render.

Form actions

Native HTML form handling with typed form actions. Zero client-side JS required for mutations.

API routes

+server.ts files export GET, POST, PATCH, DELETE handlers for REST API endpoints.

Adapters

Deploy to Vercel, Netlify, Cloudflare, Node.js, or static hosts via official adapters.

Setup

bash
npm create lunx-dev@latest my-sveltekit-app -- --framework sveltekit --ts
cd my-sveltekit-app && npm install && npm run dev

File-based routing structure

text
src/routes/
├── +layout.svelte         # Root layout (wraps all routes)
├── +layout.server.ts      # Server load for layout (auth check)
├── +page.svelte           # Homepage /
├── blog/
   ├── +page.svelte       # /blog  post listing
   ├── +page.server.ts    # Server load  fetch posts from DB
   └── [slug]/
       ├── +page.svelte   # /blog/:slug  single post
       └── +page.server.ts # Server load  fetch post by slug
├── api/
   └── users/
       └── +server.ts     # REST API  GET /api/users, POST /api/users
└── (auth)/                # Route group  shared auth layout
    ├── login/+page.svelte
    └── register/+page.svelte

Server load function + page component

typescriptsrc/routes/blog/+page.server.ts
import type { PageServerLoad } from './$types'

export const load: PageServerLoad = async ({ fetch, locals }) => {
  // locals.user set by auth hook in hooks.server.ts
  if (!locals.user) {
    redirect(302, '/login')
  }

  const posts = await fetch('/api/posts').then(r => r.json())

  return {
    user:  locals.user,
    posts,           // available as data.posts in the page
  }
}
htmlsrc/routes/blog/+page.svelte
<script lang="ts">
  import type { PageData } from './$types'
  let { data }: { data: PageData } = $props()
</script>

<h1>Blog  {data.posts.length} posts</h1>

{#each data.posts as post}
  <article>
    <h2><a href="/blog/{post.slug}">{post.title}</a></h2>
    <p>{post.excerpt}</p>
  </article>
{/each}

Form actions

typescriptsrc/routes/login/+page.server.ts
import { fail, redirect } from '@sveltejs/kit'
import type { Actions } from './$types'

export const actions: Actions = {
  default: async ({ request, cookies }) => {
    const data  = await request.formData()
    const email = data.get('email') as string
    const pass  = data.get('password') as string

    if (!email || !pass) {
      return fail(400, { error: 'Email and password required' })
    }

    const user = await verifyCredentials(email, pass)
    if (!user) {
      return fail(401, { error: 'Invalid credentials' })
    }

    cookies.set('session', user.sessionToken, {
      path:     '/',
      httpOnly: true,
      secure:   true,
      sameSite: 'lax',
      maxAge:   60 * 60 * 24 * 30,  // 30 days
    })

    redirect(302, '/dashboard')
  }
}
Lunx + SvelteKit deployment
Use the @sveltejs/adapter-auto package — SvelteKit auto-detects your deployment target (Vercel, Netlify, Cloudflare). Lunx optimizes the build output before handing off to the SvelteKit adapter for final packaging.