NNicheStackTutorials
← All tutorials
SvelteKit

SvelteKit 404 Pages and Redirects on Cloudflare Pages

_redirects, _routes.json, and the adapter-static fallback file that Cloudflare actually respects.

·10 min read·SvelteKit
SvelteKit 404 Pages and Redirects on Cloudflare Pages cover

Tested on: SvelteKit 2.16, adapter-static 3.0, Cloudflare Pages Symptom: Custom 404 page shows locally, generic Cloudflare 404 in production.

adapter-static fallback

svelte.config.js:

adapter: adapter({
  pages: 'build',
  assets: 'build',
  fallback: '404.html',
  strict: true
})

Create src/routes/+error.svelte:

<script lang="ts">
  import { page } from '$app/stores';
</script>

<h1>{$page.status}: {$page.error?.message ?? 'Not found'}</h1>
<a href="/">Go home</a>

SvelteKit generates build/404.html from this.

Cloudflare Pages config

Build command: npm run build Build output directory: build

_redirects for SPA fallback (static sites)

static/_redirects:

/old-blog/*  /blog/:splat  301
/tools       /tools/       301
/*           /404.html     404

Wait — that last line breaks SvelteKit static routing.

The correct _redirects for SvelteKit static

SvelteKit emits real HTML files per route. You do NOT need a catch-all SPA fallback.

static/_redirects:

# Redirects only — no catch-all
/old-url    /new-url/   301
/blog/rss   /rss.xml    301

Cloudflare serves about/index.html for /about/ automatically.

Error I caused

/*    /index.html   200

This is for SPAs. SvelteKit static is not an SPA. Every URL returned the homepage with 200. SEO nightmare.

Custom 404 on Cloudflare

Dashboard → Pages → your project → Custom pages → 404 → /404.html

Or in static/_redirects:

/nonexistent-path  /404.html  404

Only for actual missing paths. Don't use /*.

_headers (bonus)

static/_headers:

/_app/immutable/*
  Cache-Control: public, max-age=31536000, immutable

/*.html
  Cache-Control: public, max-age=0, must-revalidate

Verify

npm run build
curl -I https://yoursite.pages.dev/definitely-missing
# Expect: 404, body from your +error.svelte

Result

Custom 404: working
301 redirects: 4 rules, zero redirect chains
Accidental SPA fallback: removed
Google Search Console soft-404 errors: cleared in 5 days

Tags: SvelteKitCloudflare Pages404Redirects