Prerendering SvelteKit Routes for Search Engines

SvelteKit server-renders by default, so it avoids the empty-shell problem out of the box β€” but for routes whose content only changes at build time, prerendering to static HTML is faster and even more crawl-reliable. The skill is choosing prerender versus SSR per route and making sure prerenderable routes are discoverable. This builds on the SvelteKit SEO and routing guide and the rendering-strategy framework.

Step-by-step fix

  1. Enable prerender on static routes. Export prerender from the page or layout.

    // src/routes/blog/[slug]/+page.js
    export const prerender = true; // βœ… emit static HTML at build time
  2. Prerender the whole site where appropriate, or set a default in the root layout and opt specific routes out.

    // src/routes/+layout.js β€” prerender by default
    export const prerender = true;
    // src/routes/account/+page.js β€” opt this dynamic route out
    export const prerender = false; // βœ… stays SSR; per-user, not static
  3. Keep data-dependent routes on SSR. Routes reading per-request data must not be prerendered, or every visitor sees the build-time snapshot.

  4. Make prerenderable routes discoverable. The crawler that generates prerendered pages follows links; ensure dynamic route entries are reachable or listed.

    // svelte.config.js β€” seed entries the link crawler can't reach
    kit: { prerender: { entries: ['/blog/first-post', '/blog/second-post'] } }
Per-route prerender intent in SvelteKit Routes exporting prerender true are walked by the build crawler into static HTML, while prerender false routes bypass it and stay server-rendered per request. One flag per route decides the build output /blog/[slug] prerender = true Build crawler follows links + entries Static HTML first-post/index.html /account prerender = false SSR per request never frozen at build bypasses the crawler
Export prerender = true and the build crawler emits static HTML; leave it false and the route stays server-rendered on every request.

Validation

  • Build output contains static .html files for prerendered routes.
  • curl of a prerendered route returns full content and metadata.
  • GSC URL Inspection rendered HTML matches the live page.
  • Dynamic routes still reflect fresh data and are not accidentally frozen.
Choosing prerender versus SSR for a SvelteKit route If a route's content depends on per-request data it stays server-rendered with prerender false; if it is the same for every visitor it exports prerender true and emits static HTML. One question decides prerender versus SSR a route per-request data? yes prerender = false SSR, fresh every request no prerender = true static HTML at build time
Prerender routes whose content is identical for every visitor; keep per-request routes on SSR by exporting prerender false.

Reference

// Per-route rendering intent in SvelteKit
// src/routes/+layout.js
export const prerender = true;            // default: static

// src/routes/products/[id]/+page.server.js
export const prerender = false;           // SSR: live inventory
export async function load({ params }) {
  return { product: await getProduct(params.id) };
}
Prerendering a per-request route freezes its data at build time Marking a data-dependent product route prerender true bakes the build-time value into static HTML so every visitor sees a stale snapshot, whereas prerender false keeps it server-rendered and current. Don't prerender routes that read per-request data prerender = true on /products/42 build time price frozen every visitor sees old price ✗ stale snapshot prerender = false on /products/42 each request reads live data every visitor sees current price ✓ always fresh
Prerendering a route that depends on live data serves a build-time snapshot to everyone; keeping it on SSR renders the current value per request.

Frequently Asked Questions

Is SvelteKit server-rendered by default? Yes. SvelteKit server-renders pages by default, so content and metadata are in the response. Prerendering goes a step further for routes that do not change per request, emitting static HTML at build time for the best performance and crawl reliability.

When should I prerender a SvelteKit route instead of using SSR? Prerender routes whose content is the same for every visitor and changes only at build β€” marketing pages, docs, blog posts. Keep SSR for routes that depend on per-request data such as inventory or personalization.

← Back to SvelteKit SEO & Routing Guide