Skip to main content
Throughout this documentation, you’ll see references to the standard Web APIs that SvelteKit builds on top of. Rather than reinventing the wheel, we use the platform, which means your existing web development skills are applicable to SvelteKit. Conversely, time spent learning SvelteKit will help you be a better web developer elsewhere.
These APIs are available in all modern browsers and in many non-browser environments like Cloudflare Workers, Deno, and Vercel Functions. During development, and in adapters for Node-based environments (including AWS Lambda), they’re made available via polyfills where necessary.

Fetch APIs

SvelteKit uses fetch for getting data from the network. It’s available in hooks and server routes as well as in the browser.
A special version of fetch is available in load functions, server hooks and API routes for invoking endpoints directly during server-side rendering, without making an HTTP call, while preserving credentials. To make credentialled fetches in server-side code outside load, you must explicitly pass cookie and/or authorization headers. It also allows you to make relative requests, whereas server-side fetch normally requires a fully qualified URL.
Besides fetch itself, the Fetch API includes the following interfaces:

Request

An instance of Request is accessible in hooks and server routes as event.request. It contains useful methods like request.json() and request.formData() for getting data that was posted to an endpoint.
src/routes/api/user/+server.js
/** @type {import('./$types').RequestHandler} */
export async function POST({ request }) {
  const data = await request.json();
  // Process the data
  return new Response('OK');
}

Response

An instance of Response is returned from await fetch(...) and handlers in +server.js files. Fundamentally, a SvelteKit app is a machine for turning a Request into a Response.
src/routes/api/data/+server.js
import { json } from '@sveltejs/kit';

/** @type {import('./$types').RequestHandler} */
export function GET() {
  return json({ message: 'Hello world' });
}
SvelteKit provides helper functions like json() and error() to make it easier to create Response objects.

Headers

The Headers interface allows you to read incoming request.headers and set outgoing response.headers.
src/routes/what-is-my-user-agent/+server.js
import { json } from '@sveltejs/kit';

/** @type {import('./$types').RequestHandler} */
export function GET({ request }) {
  // Log all headers
  console.log(...request.headers);

  // Create a JSON Response using a header we received
  return json(
    {
      // Retrieve a specific header
      userAgent: request.headers.get('user-agent')
    },
    {
      // Set a header on the response
      headers: { 'x-custom-header': 'potato' }
    }
  );
}

FormData

When dealing with HTML native form submissions you’ll be working with FormData objects.
src/routes/login/+page.server.js
/** @type {import('./$types').Actions} */
export const actions = {
  login: async ({ request }) => {
    const data = await request.formData();
    const username = data.get('username');
    const password = data.get('password');
    
    // Process login
    return { success: true };
  }
};
<script>
  import { enhance } from '$app/forms';
</script>

<form method="POST" action="?/login" use:enhance>
  <input name="username" type="text" />
  <input name="password" type="password" />
  <button>Log in</button>
</form>

Stream APIs

Most of the time, your endpoints will return complete data. Sometimes, you may need to return a response that’s too large to fit in memory in one go, or is delivered in chunks, and for this the platform provides streams:
Example: Streaming response
export function GET() {
  const stream = new ReadableStream({
    start(controller) {
      controller.enqueue('chunk 1');
      controller.enqueue('chunk 2');
      controller.close();
    }
  });
  
  return new Response(stream);
}

URL APIs

URLs are represented by the URL interface, which includes useful properties like origin and pathname (and, in the browser, hash). This interface shows up in various places:
  • event.url in hooks and server routes
  • $page.url in pages
  • from and to in beforeNavigate and afterNavigate
src/routes/blog/+page.server.js
/** @type {import('./$types').PageServerLoad} */
export function load({ url }) {
  console.log(url.pathname);  // '/blog'
  console.log(url.origin);    // 'https://example.com'
  console.log(url.href);      // 'https://example.com/blog?page=1'
  
  const page = url.searchParams.get('page');
  return { page };
}

URLSearchParams

Wherever you encounter a URL, you can access query parameters via url.searchParams, which is an instance of URLSearchParams:
const foo = url.searchParams.get('foo');
const bar = url.searchParams.getAll('bar'); // for multiple values
const has = url.searchParams.has('baz');
src/routes/search/+page.server.js
/** @type {import('./$types').PageServerLoad} */
export function load({ url }) {
  const query = url.searchParams.get('q');
  const page = Number(url.searchParams.get('page')) || 1;
  const filters = url.searchParams.getAll('filter');
  
  return {
    query,
    page,
    filters,
    results: performSearch(query, { page, filters })
  };
}

function performSearch(query, options) {
  // Search implementation
  return [];
}

Web Crypto

The Web Crypto API is made available via the crypto global. It’s used internally for Content Security Policy headers, but you can also use it for things like generating UUIDs:
const uuid = crypto.randomUUID();
src/lib/server/crypto.js
/**
 * Hash a password using SHA-256
 * @param {string} password
 */
export async function hashPassword(password) {
  const encoder = new TextEncoder();
  const data = encoder.encode(password);
  const hash = await crypto.subtle.digest('SHA-256', data);
  
  // Convert to hex string
  return Array.from(new Uint8Array(hash))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}

Benefits of using web standards

By building on web standards, SvelteKit provides several advantages:

Transferable skills

Knowledge you gain is applicable across the web platform, not just SvelteKit

Future-proof

As browsers add new features, SvelteKit apps benefit automatically

Better compatibility

Code works across different runtimes: Node.js, Deno, Cloudflare Workers, etc.

Reduced learning curve

If you know web APIs, you already know much of SvelteKit

Next steps