DEV Community

Alex Spinov
Alex Spinov

Posted on

SvelteKit Has a Free API — Full-Stack Svelte with Zero Boilerplate

SvelteKit is the official full-stack framework for Svelte. File-based routing, SSR, API routes, form actions — everything you need to build production apps with the simplest component model in web dev.

Why SvelteKit?

  • No virtual DOM — Svelte compiles to surgical DOM updates
  • File-based routingsrc/routes/about/+page.svelte = /about
  • Server + Client — load data on server, render on client
  • Form Actions — progressive enhancement built-in
  • Adapters — deploy to Vercel, Cloudflare, Node, static

Quick Start

npm create svelte@latest myapp
cd myapp
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Pages and Layouts

<!-- src/routes/+page.svelte -->
<script>
  export let data;
</script>

<h1>Welcome, {data.user.name}!</h1>
<ul>
  {#each data.posts as post}
    <li><a href="/posts/{post.id}">{post.title}</a></li>
  {/each}
</ul>
Enter fullscreen mode Exit fullscreen mode
// src/routes/+page.server.ts
export const load = async ({ locals }) => {
  const user = await locals.db.getUser();
  const posts = await locals.db.getPosts();
  return { user, posts };
};
Enter fullscreen mode Exit fullscreen mode

Dynamic Routes

<!-- src/routes/posts/[id]/+page.svelte -->
<script>
  export let data;
</script>

<h1>{data.post.title}</h1>
<p>{data.post.content}</p>
Enter fullscreen mode Exit fullscreen mode
// src/routes/posts/[id]/+page.server.ts
export const load = async ({ params }) => {
  const post = await db.getPost(params.id);
  if (!post) throw error(404, 'Not found');
  return { post };
};
Enter fullscreen mode Exit fullscreen mode

Form Actions (No Client JS Needed)

// src/routes/login/+page.server.ts
export const actions = {
  default: async ({ request, cookies }) => {
    const data = await request.formData();
    const email = data.get('email');
    const password = data.get('password');

    const user = await authenticate(email, password);
    if (!user) return fail(401, { email, incorrect: true });

    cookies.set('session', user.token, { path: '/' });
    throw redirect(303, '/dashboard');
  },
};
Enter fullscreen mode Exit fullscreen mode
<!-- src/routes/login/+page.svelte -->
<script>
  import { enhance } from '$app/forms';
  export let form;
</script>

<form method="POST" use:enhance>
  <input name="email" value={form?.email ?? ''} />
  {#if form?.incorrect}
    <p class="error">Invalid credentials</p>
  {/if}
  <input name="password" type="password" />
  <button>Log in</button>
</form>
Enter fullscreen mode Exit fullscreen mode

API Routes

// src/routes/api/users/+server.ts
import { json } from '@sveltejs/kit';

export async function GET() {
  const users = await db.getUsers();
  return json(users);
}

export async function POST({ request }) {
  const body = await request.json();
  const user = await db.createUser(body);
  return json(user, { status: 201 });
}
Enter fullscreen mode Exit fullscreen mode

Hooks (Middleware)

// src/hooks.server.ts
export const handle = async ({ event, resolve }) => {
  const session = event.cookies.get('session');
  event.locals.user = session ? await getUser(session) : null;
  return resolve(event);
};
Enter fullscreen mode Exit fullscreen mode

Need dynamic data for your SvelteKit app? Check out my Apify actors for web scraping APIs, or email spinov001@gmail.com for custom solutions.

SvelteKit, Next.js, or Nuxt — which meta-framework wins? Share below!

Top comments (0)