Short answer, match rendering to freshness need #
Prerender pages that look the same for everyone until the next deploy: landing pages, pricing, docs, marketing content. Fast delivery, crawler-friendly HTML, edge caching essentially free.
Use server-side rendering per request when HTML depends on the user, session, or fresh data: dashboards, account pages, personalized feeds. Correct content per visitor, at the price of server work on every hit.
Use client-side rendering as a shell sparingly, mostly behind login where SEO pressure drops and interaction density justifies a client boot.
This post is a decide/compare guide to picking prerender, SSR, or CSR per SvelteKit route. If you want the learn/define concept instead — what prerendering is and which pages to keep dynamic — see What Is Prerendering.
In SvelteKit you never pick one globally. You mix per route, and the framework gives you three switches to do it.
What does each strategy do? #
A CSR shell ships near-empty HTML plus JavaScript, then renders in the browser. Flexible for app-like interaction. Weak for first paint and indexing, because content arrives only after scripts download, parse, and execute. As the page grows, so does the bundle, and mobile users feel every kilobyte.
SSR per request renders full HTML on the server for every visit, then hydrates it into an interactive app. Crawlers and visitors get real content immediately. The server pays per request: compute time, data fetching, slower time to first byte under load.
Prerendering computes HTML at build time and saves static files. Same benefits as server pages for readers, zero per-visitor compute, deployable to plain CDNs. The tradeoff is staleness by design. Content updates only when you rebuild, and generating a file per URL gets painful for huge personalized sitemaps.
Hydration connects server HTML to client interactivity. Components initialize with the data the server already fetched, event listeners attach, the page wakes up. The web.dev rendering guide states the core warning plainly: server-rendered pages can appear loaded while remaining unresponsive until client scripts execute, which on mobile can frustrate users staring at a dead page, as stated by Osmani and Miller (rendering on the web).
Think of it like a restaurant. Prerendering is meal prep, cooked once, served instantly. SSR is cooking to order, fresh every plate, slower under a rush. CSR is handing over ingredients with a recipe card.
Comparison table #
| Criterion | Prerendering | SSR per request | CSR shell |
|---|---|---|---|
| Freshness | Deploy-time | Request-time | Client-time after fetch |
| SEO friendliness | Strong | Strong | Weak without extra work |
| Server cost | Lowest | Highest | Low, data via APIs |
| First paint | Fast | Fast HTML, needs hydration | Slower, waits on JS |
| Time to first byte | Consistently fast | Slower under load | Fast shell, slow content |
| Personalization | None natively | Native | After client fetch |
| Best fit | Marketing, docs | Dashboards, accounts | Authenticated app shells |
Read rows as tradeoffs. Speed and cacheability pull against freshness and personalization, and no strategy wins every row.
How does SvelteKit routing work in practice? #
SvelteKit renders components on the server first and sends HTML to the client, then hydrates and hands subsequent navigation to a client router, with per-page control through exports from page, layout, or server modules, as stated in the SvelteKit docs (page options).
Three exports run the show:
// src/routes/marketing/+page.js
export const prerender = true;// src/routes/dashboard/+page.js
export const prerender = false;
export const ssr = true;// src/routes/app/settings/+page.js
export const ssr = false; // client shell behind loginLayouts pass defaults downward and pages override them, so you can prerender the whole marketing section from one layout file while keeping dashboards dynamic. Routes marked for prerendering leave the dynamic server manifest, which shrinks serverless and edge functions, as stated in the SvelteKit docs (page options).
The glossary adds the mental models. Prerendering scales nearly free per visitor since files serve from CDNs, while SSR avoids the extra round trips of client-only apps and keeps pages usable when JavaScript fails, as stated in the SvelteKit docs (glossary). The same glossary warns that single-page apps serving empty shells carry large performance and SEO impacts, recommended only for narrow cases like wrapped mobile apps, as stated in the SvelteKit docs (glossary).
One classic mistake: prerendering a route that secretly depends on cookies or authorization headers. The build succeeds, every visitor sees identical HTML, and access control looks broken. The rule is strict. For a page to be prerenderable, any two users hitting it directly must get the same content from the server, as stated in the SvelteKit docs (page options). Personalized data belongs in client fetches after load, or the route belongs in SSR.
Pages with form actions cannot be prerendered either, since a server must handle the posts. And disabling both ssr and csr renders nothing at all, which the docs flag with justified alarm.
Try it: Sitemap Generator
How does SEO differ across the three? #
Google processes JavaScript pages in three phases, crawl, render, then index, running scripts with an evergreen Chromium, as stated in the Google docs (JavaScript SEO basics). Client rendering can work. It often takes longer to be indexed, needs extra testing, and leans on workarounds like dynamic rendering for heavy architectures, as stated by the web.dev guide (rendering on the web).
So the SEO ranking is not close. Prerendered and server HTML arrive complete for any crawler, including the limited ones. Client shells gamble on every bot executing JavaScript correctly and patiently. Public content should never take that bet.
Hydration and performance discipline #
Server HTML alone does not make an app fast. After markup arrives, the framework downloads, parses, and executes JavaScript to attach interactivity, and that bill lands on the main thread.
Keep it small. Ship less JavaScript on content routes, defer non-critical components, avoid deep client-only trees above the fold, and measure time to interactive on real mobile hardware instead of a desktop with fiber. Aggressive code splitting and lazy loading are the standard prescription for bundle-heavy experiences, as stated by Osmani and Miller (rendering on the web).
Static-first public pages plus lean SSR for authenticated pages is a durable default. Crawlers and visitors get fast content, server work concentrates where personalization justifies it, and CSR shells stay quarantined behind login walls.
What we learned building this #
In BYOB we set render choice per route with framework page options. Marketing, blog, and tool routes stay prerender friendly while dashboard and API routes stay server rendered. This mix is documented in the how BYOB uses SvelteKit guide and matches the short answer in the post: use prerender where content is same for everyone and server rendering where it must reflect the user.
Who this is for (and who should skip it) #
This fits SvelteKit teams choosing how each route should render. If you run a mix of marketing pages plus authenticated dashboards you will use more than one strategy and this shows where each earns its keep.
Skip fine tuning if your site is a few static pages with no login. Prerender everything and move on until fresh per user HTML becomes a real requirement.
- Best for developers choosing render modes across marketing plus dashboard routes.
- Best for startups mixing static pages with logged in views.
- Best for beginners prerendering a few pages before adding dynamic needs.
Verdict, static by default and dynamic on purpose #
Prerender what rarely changes. Server-render what must be fresh and personal. Client-render only the shells where login walls remove SEO pressure and interaction density earns a boot.
For most builder-style sites, landing page plus app, that means static marketing, SSR dashboards, and no global client takeover. Let each route earn its strategy from freshness, SEO, and hydration evidence. Measure the bottlenecks first, as the rendering guide advises, then pick the cheapest strategy that survives contact with your constraints.