Skip to main content
The @sveltejs/adapter-netlify adapter deploys your SvelteKit app to Netlify.

Installation

npm install -D @sveltejs/adapter-netlify

Usage

Add the adapter to your svelte.config.js:
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-netlify';

/** @type {import('@sveltejs/kit').Config} */
const config = {
  kit: {
    adapter: adapter({
      edge: false,
      split: false
    })
  }
};

export default config;

Configuration options

From the adapter type definitions:
/// file: packages/adapter-netlify/index.d.ts
export default function plugin(opts?: { 
  split?: boolean;   // Split into multiple functions
  edge?: boolean;    // Use Netlify Edge Functions
}): Adapter;

split

If true, creates a separate Netlify function for each route. This can improve cold start times but may hit function limits on large sites.
adapter({
  split: true  // One function per route
})
From the implementation:
/// file: packages/adapter-netlify/index.js
if (split) {
  for (let i = 0; i < builder.routes.length; i++) {
    const route = builder.routes[i];
    if (route.prerender === true) continue;
    
    const parts = [];
    for (const segment of route.segments) {
      if (segment.rest) {
        parts.push('*');
      } else if (segment.dynamic) {
        parts.push(`:param${parts.length}`);
      } else {
        parts.push(segment.content);
      }
    }
    
    const pattern = `/${parts.join('/')}`;
    const name = FUNCTION_PREFIX + 
      (parts.join('-').replace(/[:.]/g, '_').replace('*', '__rest') || 'index');
    
    generate_serverless_function({ builder, routes, patterns, name });
  }
}

edge

Deploys to Netlify Edge Functions instead of serverless functions. Edge Functions run on Deno at the edge, closer to your users.
adapter({
  edge: true  // Use edge runtime
})
You cannot use both split: true and edge: true together. Edge Functions do not support splitting.

Netlify configuration

Create a netlify.toml file to configure your deployment:
[build]
  command = "npm run build"
  publish = "build"

[build.environment]
  NODE_VERSION = "20"

[[redirects]]
  from = "/old-path"
  to = "/new-path"
  status = 301
The adapter automatically detects the publish directory from netlify.toml:
/// file: packages/adapter-netlify/index.js
function get_publish_directory(netlify_config, builder) {
  if (netlify_config) {
    if (!netlify_config.build?.publish) {
      builder.log.minor('No publish directory specified in netlify.toml, using default');
      return;
    }
    
    if (resolve(netlify_config.build.publish) === process.cwd()) {
      throw new Error(
        'The publish directory cannot be set to the site root. ' +
        'Please change it to another value such as "build" in netlify.toml.'
      );
    }
    return netlify_config.build.publish;
  }
}

Custom headers and redirects

You can add custom headers and redirects by creating _headers and _redirects files in your project root:
# Cache immutable assets
/_app/immutable/*
  Cache-Control: public, immutable, max-age=31536000

# Security headers
/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
The adapter preserves these files and adds SvelteKit-generated headers:
/// file: packages/adapter-netlify/index.js
builder.log.minor('Writing custom headers...');
const headers_file = join(publish, '_headers');
builder.copy('_headers', headers_file);
appendFileSync(
  headers_file,
  `\n\n/${builder.getAppPath()}/immutable/*\n  cache-control: public\n  cache-control: immutable\n  cache-control: max-age=31536000\n`
);
Place _headers and _redirects in your project root, not in the static directory. The adapter will throw an error if they’re in the wrong location.

Platform context

Netlify provides a context object with request and environment information:
/// file: src/hooks.server.js
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
  // Access Netlify context (when using Edge Functions)
  console.log('Deploy ID:', event.platform?.context?.deploy?.id);
  console.log('Geo location:', event.platform?.context?.geo);
  
  return resolve(event);
}

Build output

The adapter generates different output based on your configuration:
.netlify/
├── functions-internal/
│   ├── sveltekit-render.mjs        # Main function
│   └── sveltekit-render.mjs.map    # Source map
├── server/                          # Server code
├── serverless.js                    # Function wrapper
└── package.json

build/                               # Published directory
├── _headers                         # HTTP headers
├── _redirects                       # Redirect rules
└── ...                             # Static assets

Deployment

1

Build locally

npm run build
2

Deploy

netlify deploy --prod

Environment variables

Set environment variables in the Netlify UI or via netlify.toml:
[build.environment]
  DATABASE_URL = "postgresql://..."
  API_KEY = "secret-key"

[context.production.environment]
  NODE_ENV = "production"

[context.deploy-preview.environment]
  NODE_ENV = "staging"
Access them in your app:
import { env } from '$env/dynamic/private';

export async function load() {
  const data = await fetch(env.DATABASE_URL);
  // ...
}
Netlify automatically sets NETLIFY=true during builds, which is how adapter-auto detects the Netlify environment.

Edge Functions vs Serverless

FeatureEdge FunctionsServerless Functions
RuntimeDeno at the edgeNode.js in US East
Cold startFaster (~0-10ms)Slower (~50-200ms)
Execution timeUp to 50sUp to 26s
Node APIsLimitedFull support
NPM packagesMost workAll work
SplittingNot supportedSupported
Edge Functions run on Deno, not Node.js. Some Node.js-specific packages may not work. Test thoroughly before deploying.