SvelteKit Explained +server.js vs +page.server.js vs +page.js

sveltekit-serverjs-vs-svelte-file

SvelteKit Data Handling +server.js vs +page.server.js vs +page.js Explained

sveltekit svelte file system

SvelteKit Data Handling: +server.js, +page.server.js, and +page.js Explained

SvelteKit provides a powerful system for managing both server-side and client-side data fetching through three key files: +server.js, +page.server.js, and +page.js. Each plays a distinct role in handling data and optimizing performance.

1. +server.js - Standalone API Routes

Purpose

+server.js is used for handling server-side logic that isn’t directly tied to a page. It allows you to create API endpoints within your SvelteKit project.

Execution Context

Runs only on the server.

Use Cases

  • Serving non-HTML content like JSON or XML.
  • Creating standalone API routes (/api/data).
  • Handling file uploads, authentication, or background tasks.

Output

Returns non-HTML responses (e.g., JSON, XML).

Example

Located at src/routes/api/data/+server.js, it could look like this:

export function GET() {
  return new Response(JSON.stringify({ message: 'Hello from API' }), {
    headers: { 'Content-Type': 'application/json' }
  });
}

2. +page.server.js - Server-Side Data Fetching for Pages

Purpose

Handles server-side logic specific to a page, supporting SSR (Server-Side Rendering) and SEO-friendly content generation.

Execution Context

Runs only on the server.

Use Cases

  • Fetching database/API data before rendering a page.
  • Pre-rendering data for SEO and performance.
  • Server-only tasks like authentication checks.

Output

Passes data to +page.svelte for HTML rendering.

Example

Located at src/routes/blog/[slug]/+page.server.js:

export async function load({ params }) {
  const post = await fetchPostFromDatabase(params.slug);
  return { post };
}

3. +page.js - Universal Data Fetching (Client & Server)

Purpose

+page.js provides a universal loader for fetching data on both the server (initial load) and client (subsequent navigation).

Execution Context

Runs on both the server and client.

Use Cases

  • Fetching data that isn’t sensitive and can be accessed by both server and client.
  • Supporting client-side navigation without full page reloads.
  • Sharing data-fetching logic between SSR and CSR.

Output

Passes data to +page.svelte for HTML rendering.

Example

Located at src/routes/blog/[slug]/+page.js:

export async function load({ fetch, params }) {
  const response = await fetch(`/api/posts/${params.slug}`);
  const post = await response.json();
  return { post };
}

Note: When a page is first loaded, +page.js runs on the server. When navigating between pages via client-side routing, it runs on the client.


Key Differences Between +server.js, +page.server.js, and +page.js

Feature +server.js +page.server.js +page.js
Purpose Standalone server-side API or logic Server-side data fetching for specific pages Universal data fetching for server/client
Execution Context Server-only Server-only Server and client
Data Fetching Server-side, non-page related Server-side, tied to specific pages Client-side and server-side
Rendering Returns non-HTML content Used with +page.svelte for HTML rendering Used with +page.svelte for HTML rendering
Use Cases API endpoints, file uploads, etc. SSR data fetching, SEO-focused rendering Data fetching for both SSR and CSR

When to Use Each

  • Use +server.js when creating API endpoints, handling authentication, or processing server-side tasks unrelated to a specific page.
  • Use +page.server.js when you need server-only data fetching for a specific page (e.g., fetching protected or sensitive data).
  • Use +page.js for data that should be accessible on both server and client, supporting smooth client-side navigation.

By structuring your SvelteKit project properly with these files, you can optimize performance, ensure security, and enhance user experience.