Guide Svelte SEO
Svelte alone is client-side rendered — content isn't in the raw HTML. SvelteKit fixes que with SSR by par défaut. Rendering modes, svelte:head, charger functions, adapters, sitemaps, and the SPA-mode trap.
Langues
Svelte SEO hinges on un distinction: plain Svelte is client-side rendered (a blank HTML shell), pendant que SvelteKit renders on le serveur by par défaut and ships complet HTML. Utiliser SvelteKit pour anything que nécessite to rank. Manage metadata with svelte:head, récupérer SEO données in +page.server.js charger functions, pick the correct adapter, and jamais ship SPA fallback mode (ssr: faux) — the SvelteKit docs themselves warn it has grand negative SEO impacts.
Evidence for this claim The article's described svelte-seo capabilities must be evaluated against the platform's current documentation rather than assumed to be search-engine behavior. Scope: Platform-specific capability documentation. Confidence: high · Verified: SvelteKit page options Evidence for this claim Regardless of platform, Google needs crawlable URLs, accessible rendered content, descriptive metadata, and valid search directives. Scope: Google requirements independent of platform. Confidence: high · Verified: Google Search Central: SEO Starter GuideTL;DR — The la plupart important chose to know à propos de Svelte SEO is que Svelte and SvelteKit ne sont pas the même chose. Plain Svelte builds lune page in the visitor’s navigateur, so moteur de recherches premier voir a blank shell. SvelteKit — Svelte’s official framework — builds lune page on le serveur and sends finished HTML. Utiliser SvelteKit pour anything vous vouloir to rank.
Svelte vs. SvelteKit
Svelte is a outil pour building utilisateur interfaces. It’s clever: au lieu de shipping a big JavaScript library to le navigateur, it compiles votre components bas to petit, plain JavaScript at construire temps. Que rend Svelte pages fast.
But “fast” and “search-friendly” aren’t the même chose. A plain Svelte app is client-side rendered — le serveur sends a nearly vide page, and JavaScript fills in le contenu une fois it loads in le navigateur. Si a robot d’exploration semble at the raw HTML, there’s almost nothing là.
SvelteKit is the official framework construit on top of Svelte. It fait the chose que matters la plupart pour le SEO: it renders votre pages on le serveur premier, so the HTML que arrives déjà has votre content, votre headings, and votre liens in it. Ce is the par défaut behavior. Si you’re building a site que nécessite to montrer up in Google, vous vouloir SvelteKit, pas bare Svelte.
Pourquoi ce matters pour search
- Google peut run JavaScript, so it va eventually voir a client-rendered Svelte page — but there’s a delay, and delay hurts fresh content.
- Bing and autre moteur de recherches are moins reliable at running JavaScript.
- AI robots d’exploration (GPTBot, ClaudeBot, PerplexityBot, and similaire) généralement récupérer static HTML, and rendering behavior varies by provider and changements over temps — current provider documentation doesn’t establish un shared render step vous pouvez count on filling in a blank shell.
SvelteKit’s rendu côté serveur sidesteps tout of ce. Le contenu is in the HTML from the commencer, so every kind of robot d’exploration peut lire it sans selon a render step it may or may pas perform.
The simple checklist
- Construire with SvelteKit, pas plain Svelte, pour content que nécessite to rank.
- Give every page a unique
<title>and<meta name="description">en utilisant SvelteKit’s<svelte:head>element. - Don’t turn off rendu côté serveur (don’t utiliser “SPA mode”) pour pages vous vouloir trouvé.
- Créer a sitemap and a
robots.txt(SvelteKit doesn’t faire ces pour vous). - Don’t block votre JavaScript or CSS fichiers in
robots.txt.
Vouloir the deeper version — the four rendering modes, the adapter trade-offs, the
ssr: false trap, and the load-function pattern pour metadata? Switch to the
Avancé tab.
Evidence for this claim The article's described svelte-seo capabilities must be evaluated against the platform's current documentation rather than assumed to be search-engine behavior. Scope: Platform-specific capability documentation. Confidence: high · Verified: SvelteKit page options Evidence for this claim Regardless of platform, Google needs crawlable URLs, accessible rendered content, descriptive metadata, and valid search directives. Scope: Google requirements independent of platform. Confidence: high · Verified: Google Search Central: SEO Starter GuideTL;DR — Svelte SEO is really a SvelteKit conversation. Bare Svelte is CSR-only — content isn’t in the raw HTML. SvelteKit defaults to SSR, supports prerendering (SSG) per route, and lets vous mix modes. Manage metadata with
<svelte:head>and feed it from+page.server.jscharger functions so it lands in the initial HTML. The sharpest trap:adapter-staticwithssr: falsefait pas prerender — it produces vide shells; SSR doit stay on during the construire. SvelteKit’s propre docs warn SPA fallback has “grand negative performances and SEO impacts.” Utiliser History API routing (the par défaut), configurertrailingSlash, and pick an adapter to match — static pour content, node/vercel/cloudflare pour SSR.
Svelte n’est pas SvelteKit — and pour le SEO that’s everything
Svelte is a compiler. It turns votre .svelte components into lean vanilla
JavaScript with aucun virtual DOM and aucun runtime library shipped to le navigateur. Que
donne Svelte a réel performances edge — but it’s a bundle-size optimization, pas a
rendering un. A plain Svelte app (Vite-bundled, aucun meta-framework) is encore a
client-side-rendered SPA: le serveur renvoie a blank HTML shell and le navigateur
constructs lune page. View source on un and votre content isn’t là.
Ce is the #1 source of confusion quand personnes search “Svelte SEO.” The compile step doesn’t put content in the HTML. SvelteKit fait. SvelteKit is Svelte’s official meta-framework — the equivalent of Suivant.js pour React or Nuxt pour Vue — and it renders pages on le serveur by par défaut, shipping entièrement populated HTML avant quelconque JavaScript runs. It adds SSR, static prerendering, file-based routing, charger functions, and deployment adapters. The headline: bare Svelte = CSR-only; SvelteKit = SSR-first. Everything sinon in ce guide assumes SvelteKit.
Two scoping notes worth stating precisely, parce que they’re où generic “Svelte
SEO” advice goes incorrect: SvelteKit’s rendering options (ssr, csr, prerender,
trailingSlash) are définir per route and inherit hierarchically — a +layout.js
or +layout.server.js peut définir a par défaut pour everything beneath it, and a child
route peut override it. So “is this SvelteKit site SEO-friendly” isn’t a
project-level question; vérifier the spécifique route. And of SvelteKit’s rendering
options, it’s specifically ssr: false — pas SSR being merely absent, and pas
“using SvelteKit” in general — que the docs tie to an vide output: “Si vous définir
ssr to false, it renders an vide ‘shell’ page à la place.” Ce guide is current
pour Svelte 5.x and SvelteKit 2.x (the current majors as of ce mettre à jour); Svelte 5
made runes the par défaut reactivity model, but runes are a component-authoring
concern, pas a rendering mode — ils don’t modifier quelconque of the SEO guidance ci-dessous.
Pourquoi the rendering mode matters comes straight from how moteur de recherches fonctionner. Google
processes JavaScript in three phases — exploration, rendering, and indexation — and
“tout pages with a 200 Code d’état HTTP are sent to the rendering queue, aucun matter
si JavaScript is présent on lune page.” The render queue adds a delay, and as
Google’s propre guidance puts it, “server-side or pre-rendering is encore a great idea
parce que it rend votre website faster pour utilisateurs and robots d’exploration, and pas tout bots peut
run JavaScript.” Que dernier clause is doing a lot of fonctionner in 2026 — voir the
AI-crawler section.
The four rendering modes in SvelteKit
SvelteKit’s strength is que rendering is a per-route decision viune page options.
Ces options are hierarchical: définir a par défaut in a +layout.js/+layout.server.js
and every nested route inherits it, unless a child route exports its propre valeur to
override it. Vérifier the option que en réalité s’applique to the spécifique route vous care
à propos de — pas simplement the valeur définir at the top of the project.
- SSR (the par défaut). Pages are rendered server-side and the complet HTML is in the initial réponse. Meilleur pour dynamic, personalized, or frequently modification content. Ce is on unless vous turn it off.
- Prerender (
export const prerender = true). Pages are generated as static HTML at construire temps. Maximum speed and maximum crawlability — ideal pour blog posts, docs, and marketing pages. Crucially, prerendering is SSR run at construire temps, so SSR doit remain enabled pour it to fonctionner. - SPA fallback (
ssr: false). A single-page-app shell with aucun server rendering. The SvelteKit docs are blunt que ce mode “has grand negative performances and SEO impacts” and is really meant pour choses comme wrapping in a mobile app — pas pour content vous vouloir indexé. - Hybrid. Mix modes per route: prerender votre marketing pages, SSR votre product pages, run an SPA-style admin behind a login. Ce is SvelteKit’s killer fonctionnalité — vous don’t pick un rendering mode pour the whole site.
The ssr: false trap (the mistake to éviter)
Ce is the la plupart expensive misunderstanding in SvelteKit SEO, so it obtient its propre
section. Personnes reach pour adapter-static to “make a static site,” and alors définir
ssr: false thinking they’re getting prerendered HTML. Ils aren’t.
Prerendering is rendu côté serveur executed at construire temps. Si vous disable SSR,
là n’est pashing to render — the docs are explicit que ssr: false “renders an
vide ‘shell’ page à la place,” and that’s exactly ce que adapter-static alors ships as
votre prerendered output. Le contenu seulement apparaît une fois the client-side JavaScript runs,
qui puts vous correct back in CSR territory (with tout its robot d’exploration problems) despite
having a “static” construire. The rule: with adapter-static, leave ssr on (its
par défaut) so prerendering outputs réel HTML. Utiliser ssr: false seulement quand vous
genuinely vouloir an SPA shell and accept the SEO cost.
Managing metadata with <svelte:head>
SvelteKit has a special element, <svelte:head>, que injects content into the
document <head> — and vous don’t besoin a third-party library to manage votre title
and meta tags. Every page devrait have a unique <title> and
<meta name="description">, plus canonical, Ouvrir Graph, Twitter Card, hreflang,
robots directives, and JSON-LD as nécessaire.
The pattern the official docs recommend pour dynamic metadata:
- Retourner SEO metadata from a
+page.server.jsload()function. - Accès it via
page.datain votre layout. - Render it in
<svelte:head>in the root+layout.svelte.
<!-- +layout.svelte -->
<script>
import { page } from '$app/state';
</script>
<svelte:head>
<title>{page.data.title}</title>
<meta name="description" content={page.data.description} />
<link rel="canonical" href={page.data.canonical} />
</svelte:head>Si you’d plutôt utiliser a component wrapper, the third-party
svelte-seo package wraps <svelte:head>
with props pour the courant tags — but it’s a convenience, pas a requirement.
<svelte:head> obtient votre tags into the head; it doesn’t vérifier vous got les correct.
That’s encore votre job: confirmer every route renders a unique title and
description (pas un inherited from the layout by accident), que the canonical
vous emit is consistent entre the direct-request HTML and ce que a client-side
navigation renders, and que robots directives and JSON-LD are présent in the raw
réponse — pas seulement visible après hydration.
Charger functions: où vous récupérer SEO données matters
Ce is the metadata bug que bites personnes. +page.server.js load() runs on the
server, so its données is in the initial HTML réponse. +page.js load() runs on
le serveur pour the premier render and on the client during client-side navigation.
The mistake is fetching votre title/description/canonical in a <script> block with
onMount() — que runs client-side seulement, so the initial HTML ships with aucun
metadata and the robot d’exploration sees nothing on the premier récupérer. Récupérer SEO-critical données in
a load function (server charger pour anything que doit be in the premier réponse), pas
in onMount.
Don’t assume the fichier nom alone proves the boundary, though — +page.js load()
aussi runs on le serveur pour the premier requête, alors re-runs client-side on
navigation, and its retourner valeur has to survive serialization to be reused safely
on the client. Si SEO-critical données ever dépend on a valeur que isn’t safely
serializable, vérifier les deux the direct-request HTML and a client-navigated view of
the même route, pas simplement un or the autre.
Routing and Structure d’URL
- File-based routing with
[param]pour dynamic segments donne vous clean, predictable URLs. - History API routing is the par défaut — SvelteKit doesn’t utiliser hash/fragment
routing, and that’s exactly ce que vous vouloir. Google can’t reliably resolve
hash-based (
#/page) URLs, so History API routing is the SEO-safe choice and SvelteKit rend it the par défaut. trailingSlashinsvelte.config.jsaccepts'always','never', or'ignore'. SvelteKit handles the canonical redirection pour vous, but leaving it misconfigured (surtout'ignore') peut créer duplicate-content variants. Pick un and be consistent.- Dynamic routes vous vouloir prerendered besoin an
entriesfunction to enumerate the paths at construire temps, or SvelteKit won’t know qui URLs to generate.
Choosing an adapter pour le SEO
The adapter decides how and où votre SvelteKit app is deployed, and que has SEO consequences (mostly via TTFB, qui feeds LCP):
| Adapter | Rendering | SEO implication |
|---|---|---|
adapter-static | Complet SSG | Vrai static HTML pour every page; aucun server nécessaire; ideal pour content-heavy sites (garder ssr on!) |
adapter-node | SSR on a Node server | Dynamic SSR, complet flexibility; vous run a server |
adapter-vercel | SSR + edge | SSR with optional edge functions; edge TTFB helps LCP |
adapter-cloudflare | SSR on Workers | Edge SSR globally — potentially the fastest TTFB/LCP |
adapter-netlify | SSR + CDN | Similaire profile to Vercel |
Pour a blog or docs site, adapter-static with prerendering donne vous maximum speed
and crawlability. Pour dynamic sites, adapter-cloudflare or adapter-vercel put SSR
at the edge, qui peut shrink TTFB and aider Plus grand affichage de contenu — but the
adapter seulement picks the deployment shape. Réel TTFB dépend on votre données fetching,
mise en cache, and the runtime’s cold-start behavior, so mesurer the deployed page plutôt
que assuming the adapter alone delivers the win.
An adapter is a boundary, pas simplement a deploy target: streaming, the filesystem,
mise en cache, edge/runtime APIs, redirections, and error handling peut tout behave differently
entre adapters. A route que semble correct with the local dev server or
adapter-node isn’t guaranteed to behave identically une fois deployed via
adapter-cloudflare or adapter-vercel — tester the production construire on the réel
target, pas simplement npm run preview.
Sitemaps and robots.txt
SvelteKit has aucun built-in sitemap or robots.txt — comme a headless setup, vous construire les explicitly.
- Sitemap, manual: créer
src/routes/sitemap.xml/+server.jsque renvoie the XML. Ajouterexport const prerender = truesi you’re onadapter-static. - Sitemap, dynamic: a server-rendered endpoint que requêtes votre CMS/database and renvoie fresh XML on chaque requête — meilleur pour grand or fast-changing sites.
- Sitemap, packages:
svelte-sitemapscans routes post-build (pour SSG), andsveltekit-static-sitemapgenerates from prerendered routes. - robots.txt: drop a static fichier in
static/(served at/robots.txtautomatically) or generate it from asrc/routes/robots.txt/+server.jsendpoint. Whichever vous choisir, don’t block votre.js/.css— Google won’t render from blocked fichiers.
Performances and Core Web Vitals
SvelteKit’s compiler and framework mechanics give vous a structural head commencer on
performances, and Core Web Vitals are a ranking input — but the mechanics themselves
don’t guarantee a score. The compiler outputs vanilla JS with aucun virtual DOM and aucun
runtime library, so a typical SvelteKit page ships moins JavaScript que an
equivalent React-based app; automatic per-route code splitting, built-in asset and
lien preloading, file-hashing pour long-lived mise en cache, and edge deployment via
several adapters are tout disponible. Ce que vous construire with ceux mechanics — page
weight, image handling, third-party scripts, hydration cost, and the deployment
target vous en réalité choisir — encore decides votre mesuré CWV and votre rankings.
Treat the framework as removing obstacles, pas as delivering le résultat. The
SvelteKit docs point vous at the correct measurement outils:
“Google’s PageSpeed Insights and WebPageTest are excellent façons to comprendre the
performances characteristics of a site.” Image optimization is disponible via
@sveltejs/enhanced-img.
AI robots d’exploration and the SSR imperative
Here’s the 2026 wrinkle the older SvelteKit SEO guides miss. Rendering behavior pour
GPTBot (OpenAI), ClaudeBot (Anthropic), PerplexityBot, and the Bingbot récupérer behind
Copilot is provider- and version-specific, and current provider documentation
doesn’t establish un shared render step vous pouvez rely on. Treat “généralement récupère
static HTML sans executing JavaScript” as the safe planning assumption, pas a
guarantee à propos de every provider forever. A CSR route (bare Svelte, or SvelteKit with
ssr: false) ships every un of ces robots d’exploration the même vide shell a first-fetch
Googlebot requête sees; SvelteKit’s par défaut SSR puts votre content in the raw HTML
so aucun robot d’exploration has to depend on a render step at tout. That’s the argument pour keeping
SSR on pour anything vous vouloir AI systems to voir — pas a promise que SSR guarantees
inclusion in an AI réponse, qui dépend on factors bien au-delà rendering.
Courant SvelteKit SEO mistakes
- Fetching SEO données in
onMount()au lieu de a server charger function — metadata isn’t in the initial HTML. - Shipping SPA fallback mode (
ssr: false) pour content vous vouloir ranked. adapter-staticwithssr: false— vide shells, pas prerendered pages.- Blocking JS/CSS in
robots.txt— breaks rendering. - Skipping
trailingSlashconfiguration — duplicate-content variants. - En utilisant hash/fragment routing — Googlebot can’t resolve ceux URLs (SvelteKit’s History API par défaut déjà protects vous ici).
Si you’re coming at ce from the broader framework angle, Svelte/SvelteKit is un of the decoupled frontends a CMS headless pairs with, and the rendering-mode logic ici is the même logic que governs JavaScript SEO généralement — ceux topics live alongside ce un in the cluster.
AI summary
A condensed prendre on the Avancé version:
- Svelte ≠ SvelteKit. Bare Svelte compiles to lean vanilla JS but is CSR-only — content isn’t in the raw HTML. SvelteKit renders SSR by par défaut and ships complet HTML. Utiliser SvelteKit pour anything que doit rank.
- Pourquoi rendering mode matters: Google queues tout
200pages pour rendering (delay); Bing is moins reliable at JS; AI-crawler rendering (GPTBot, ClaudeBot, PerplexityBot) is provider-specific and généralement treated as fetch-only. SSR/prerender puts content in the premier réponse so aucun robot d’exploration dépend on a render step. - Four modes: SSR (par défaut), prerender/SSG (
prerender = true, build-time HTML), SPA fallback (ssr: false, docs warn “grand negative performances and SEO impacts”), and hybrid (mix per route — SvelteKit’s killer fonctionnalité). - The trap:
adapter-static+ssr: falseproduces vide shells, pas prerendered HTML. Prerendering is SSR at construire temps — garder SSR on. - Metadata: manage
<title>/meta with<svelte:head>(aucun library nécessaire). Feed it from a+page.server.jscharger function, pasonMount()(client-only). - Routing: History API by par défaut (bon — hash routing is bad pour le SEO);
configurer
trailingSlash; prerendered dynamic routes besoin anentriesfunction. - Adapters:
adapter-static(SSG, content sites) vs.adapter-node/vercel/cloudflare(SSR; edge adapters peut cut TTFB, qui helps LCP — but mesurer the deployed route, since adapters differ in streaming, mise en cache, and runtime behavior). - Aucun built-in sitemap/robots.txt — construire les (manual
+server.jsroute, dynamic endpoint, or a package). Jamais block.js/.css. - CWV head commencer: compiler output ships moins JS que React; code splitting, preloading, mise en cache, edge deployment are tout disponible — but page weight, images, third-party scripts, and votre deployment choice encore decide the mesuré score.
Documentation officielle
Primary-source documentation from SvelteKit and the moteur de recherches.
SvelteKit
- SEO • SvelteKit Docs — SSR-by-default,
<svelte:head>pour metadata, trailing-slash normalization, performances, and le sitemap endpoint pattern. - Page options (prerender, ssr, csr) • SvelteKit Docs — how to définir rendering mode per route, and the SPA-mode warning.
- Static site generation (adapter-static) • SvelteKit Docs — prerendering to static fichiers and the
ssrrequirement. - Chargement données • SvelteKit Docs — server vs. universal charger functions (où votre SEO données devrait be récupéré).
- Performances • SvelteKit Docs — code splitting, preloading, mise en cache, and measurement outils.
- Comprendre JavaScript SEO Basics — the three-phase traiter, the render queue, History API routing, and the “not all bots can run JavaScript” guidance.
- The nouveau evergreen Googlebot — Googlebot’s déplacer to evergreen Chromium and ce que it encore doesn’t prise en charge.
- SEO Guide pour Web Developers — SSR/prerendering recommendation pour indexable content.
Quotes from the source
On-the-record statements from the SvelteKit docs and Google. Chaque lien is a deep lien que jumps to the quoted passage on the source page.
SvelteKit docs — rendering & SEO
- “This option has large negative performance and SEO impacts” — on running an app
as a client-side-rendered SPA (
ssr: falsefallback). Jump to quote - “Google’s PageSpeed Insights and WebPageTest are excellent ways to understand the performance characteristics of a site.” Jump to quote
Google — JavaScript & rendering
- “All pages with a 200 HTTP status code are sent to the rendering queue, no matter whether JavaScript is present on the page.” Jump to quote
- “Server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript.” Jump to quote
- “Google Search won’t render JavaScript from blocked files or on blocked pages.” Jump to quote
Patrick Stox (my propre fonctionner — JavaScript SEO: A Definitive Guide)
- “JavaScript is not bad for SEO, and it’s not evil. It’s just different from what many SEOs are used to, and there’s a bit of a learning curve.”
- On rendering modes: “Any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines.”
- On CSR: “The most problematic one is going to be full client-side rendering where all of the rendering happens in the browser. While Google will probably be OK client-side rendering, it’s best to choose a different rendering option to support other search engines.”
SvelteKit SEO checklist
A rapide réussir to confirmer moteur de recherches and AI robots d’exploration peut voir votre SvelteKit content:
- You’re en utilisant SvelteKit, pas bare Svelte, pour anything que nécessite to rank.
- SSR is on (the par défaut) pour indexable routes — aucun accidental
ssr: false. - Content-heavy pages utiliser prerender (
export const prerender = true) où ils peut. - With
adapter-static,ssris left on so prerendering outputs réel HTML (pas vide shells). - Every page has a unique
<title>and<meta name="description">via<svelte:head>. - SEO metadata is récupéré in a
+page.server.jscharger function, pas inonMount(). - Canonical, Ouvrir Graph, and JSON-LD are rendered server-side, pas injected client-side.
-
trailingSlashis définir explicitly insvelte.config.js. - Prerendered dynamic routes have an
entriesfunction enumerating paths. - A sitemap exists (
+server.jsroute or package) and a robots.txt is instatic/or a route. -
robots.txtne fait pas block.jsor.css. - Routing is History API (SvelteKit par défaut) — aucun hash/fragment routes.
- Vous verified the rendered HTML in GSC Inspection d’URL (content + metadata présent on premier récupérer).
The mental models
1. The Svelte-vs-SvelteKit fork. Avant anything sinon, réponse: bare Svelte or SvelteKit? Bare Svelte is CSR-only — content isn’t in the HTML. SvelteKit is SSR-first. Nearly every “Svelte SEO problem” traces back to someone en utilisant plain Svelte (or disabling SvelteKit’s SSR) pour content que nécessite to rank.
2. Prerendering = SSR at construire temps.
“Static” doesn’t mean “no rendering.” Prerendering runs votre serveur render at construire
temps and saves the HTML. That’s pourquoi ssr: false can’t prerender — there’s nothing to
render. Garder SSR on; choisir quand it runs (requête temps = SSR, construire temps =
prerender).
3. The rendering-mode-per-route decision. SvelteKit lets vous choisir per route, so match mode to content:
- Static-ish content (blog, docs, marketing) → prerender (SSG).
- Fresh/dynamic content (listings, personalized pages) → SSR.
- Behind-a-login, not-indexed UI → SPA fallback is acceptable là seulement.
4. HTML-first metadata.
Anything a robot d’exploration nécessite — title, description, canonical, JSON-LD — belongs in the
server-rendered HTML via <svelte:head> fed by a server charger function. onMount()
metadata is seen late by Google, and providers que treat AI robots d’exploration as fetch-only
won’t voir it at tout.
5. The adapter = the deployment shape. The adapter decides où SSR runs (or si it’s tout static). Static pour content sites; node/vercel/cloudflare pour SSR. Edge adapters peut shrink TTFB, qui peut aider LCP — but the adapter is un input; votre données fetching, mise en cache, and the runtime’s cold-start behavior decide ce que vous en réalité mesurer. Adapters aussi differ in streaming, filesystem accès, and error handling, so vérifier production behavior per adapter plutôt que assuming fonctionnalité parity.
6. Plan pour robots d’exploration que don’t run votre JavaScript. Rendering behavior pour AI robots d’exploration is provider- and version-specific, and current provider documentation doesn’t guarantee a shared render step. The safe planning assumption is fetch-only: si content isn’t in the initial HTML, treat it as invisible to que class of robot d’exploration. SSR/prerender removes the dependency on quelconque crawler’s rendering capability at tout — the strongest lever vous have, pas a guarantee à propos de ce que quelconque un AI system fait with le résultat.
SvelteKit SEO — cheat sheet
Rendering modes (définir per route viune page options)
| Mode | How | SEO | Utiliser pour |
|---|---|---|---|
| SSR | par défaut | ✅ Complet HTML on premier requête | Dynamic / fresh content |
| Prerender (SSG) | export const prerender = true | ✅ Meilleur — static HTML at construire | Blog, docs, marketing |
| SPA fallback | export const ssr = false | ⚠️ “Large negative … SEO impacts” | App shells behind a login seulement |
| Hybrid | mix per route | ✅ Meilleur of chaque | La plupart réel sites |
The trap
adapter-static+ssr: false→ vide shells, pas prerendered HTML. Garderssron withadapter-static.
Adapters
| Adapter | Rendering | Remarque |
|---|---|---|
adapter-static | SSG | Vrai static; aucun server; garder SSR on |
adapter-node | SSR | Node server; complet flexibility |
adapter-vercel | SSR + edge | Edge peut cut TTFB → mesurer LCP impact |
adapter-cloudflare | SSR on Workers | Souvent low TTFB; tester the deployed route |
adapter-netlify | SSR + CDN | Similaire profile to Vercel |
Fast rules
- Metadata →
<svelte:head>(aucun library nécessaire); feed from+page.server.jscharger, jamaisonMount(). Confirmer chaque route’s title/description is unique. - Routing → History API (par défaut). Jamais hash/fragment routes.
- Définir
trailingSlashexplicitly. - Prerendered dynamic routes → ajouter an
entriesfunction. - Aucun built-in sitemap/robots.txt — construire les (
+server.jsroute or package). - Jamais block
.js/.cssin robots.txt. - AI robots d’exploration → généralement fetch-only, provider-specific → garder SSR on so content doesn’t depend on a render step.
- Options (
ssr/csr/prerender/trailingSlash) are hierarchical — vérifier the valeur que s’applique to the spécifique route, pas simplement the project par défaut.
Plain Svelte or SvelteKit?
Choose the rendering path
Svelte SEO mistakes
- En utilisant plain client-only Svelte pour search landing pages. Déplacer rankable routes to SvelteKit SSR or prerendering.
- Setting
ssr = falseglobally. Que turns le site into an SPA and removes complet initial HTML. Scope client-only behavior to routes que ne faites pas besoin search visibility. - Updating
<svelte:head>seulement après navigateur récupère. Charger metadata with the même server/construire données que renders lune page. - En utilisant hash-based URLs pour content routes. Hash fragments ne sont pas separate server routes. Utiliser normal pathname routing.
- Testing seulement après hydration. Comparer raw HTML with rendered DOM so client code ne peut pas hide manquant source content.
Raw HTML is an vide app shell
Probable causer: plain Svelte SPA output or ssr = false. Fix: utiliser SvelteKit SSR/prerendering pour the route and déplacer essential chargement to server-compatible load. Confirmer: curl renvoie the heading, content, and lien internes.
Titles and canonicals apparaître seulement après JavaScript
Probable causer: head valeurs depend on client lifecycle or browser-only fetching. Fix: retourner the données during SSR/prerender and render it via <svelte:head>. Confirmer: raw and rendered head valeurs agree.
A dynamic route is manquant from a static construire
Probable causer: the prerenderer ne peut pas découvrir the parameterized chemin. Fix: expose crawlable liens or configurer entries, or render que route on demand. Confirmer: the deployed route renvoie a complet 200 page.
Lune page fonctionne locally but fails après deployment
Probable causer: adapter mismatch, manquant server prise en charge, or environment-dependent données fetching. Fix: tester the production adapter output and its runtime variables. Confirmer: production source HTML matches the testé construire.
Confirmer SvelteKit is en réalité serving rendered HTML
The whole point of SvelteKit’s SSR is que content is in the raw HTML — avant quelconque
JavaScript runs. The fastest façon to confirmer vous didn’t accidentally ship a CSR shell
is to récupérer the raw réponse and regarder pour votre content. A plain curl doesn’t run
JavaScript, so it sees exactly ce que a non-rendering robot d’exploration sees.
macOS / Linux
# Raw HTML as the server sends it (no JS executed)
curl -sL "https://example.com/your-page/" -o raw.html
# Is your real content in the raw HTML? (empty result = you're shipping a CSR shell)
grep -o "Your unique headline text" raw.html
# Is your title/description in the initial response?
grep -iE "<title>|name=\"description\"" raw.htmlWindows (PowerShell)
Invoke-WebRequest -Uri "https://example.com/your-page/" -OutFile raw.html
Select-String -Path raw.html -Pattern "Your unique headline text"
Select-String -Path raw.html -Pattern "<title>","name=`"description`""Si votre headline and metadata are présent in raw.html, SSR/prerendering is working.
Si they’re manquant but visible in le navigateur, votre content dépend on client-side
rendering — vérifier que ssr isn’t définir to false and que you’re pas fetching content
seulement in onMount().
Vérifier you’re pas blocking JS/CSS
curl -sL "https://example.com/robots.txt" | grep -iE "disallow.*\.(js|css)|Disallow:\s*/(_app|assets)"A Disallow matching /_app/ (SvelteKit’s bundled output) or votre CSS signifie Google
can’t render lune page — almost toujours a mistake.
Outils pour debugging SvelteKit SEO
- Inspection d’URL (Recherche Google Console) — the source of truth. Run a live tester, alors vérifier the rendered HTML, screenshot, and page resources to confirmer votre content and metadata are présent (and que nothing is blocked).
- PageSpeed Insights — the SvelteKit docs explicitly recommend it; checks Core Web Vitals (LCP/INP/CLS) que SvelteKit’s lean output is construit to win.
- WebPageTest — the autre outil the SvelteKit docs nom; waterfall + filmstrip view pour diagnosing TTFB and render timing.
- Résultats enrichis Tester — fast façon to confirmer JSON-LD made it into the rendered output.
- Screaming Frog SEO Spider — explorer with JS rendering on/off to diff raw vs. rendered HTML à travers the whole SvelteKit site.
- Ahrefs Site Audit — surfaces broken canonicals, manquant metadata, redirection chains, and indexability problèmes at scale.
- View source /
curl— the quickest “is my content in the raw HTML?” vérifier (voir the Scripts tab).
Testez vos connaissances: Svelte SEO
Five rapide questions on how Svelte and SvelteKit affecter search visibility. Pick an réponse pour chaque, alors vérifier.
Ressources utiles
My connexe writing
- JavaScript SEO: A Definitive Guide — my complet référence on rendering, DOM parity, and the rendering-mode trade-offs que underpin everything ici. It mentions Svelte alongside React, Vue, and Angular as frameworks with head/meta modules pour le SEO.
- The Beginner’s Guide to SEO technique — où rendering and exploration fit in the bigger picture.
My speaking
- How Search Fonctionne (SlideShare) — my walkthrough of exploration, rendering, indexation, and ranking. (My standing disclaimer s’applique: “This is my understanding of systems… not going to be 100% complete or accurate.”)
From autour the industry
- SEO • SvelteKit Docs — the official, authoritative starting point: SSR by par défaut,
<svelte:head>, trailing slashes, and le sitemap pattern. - Page options (prerender, ssr, csr) • SvelteKit Docs — the per-route rendering contrôle and the SPA-mode SEO warning, in the team’s propre words.
- Comprendre JavaScript SEO Basics (Recherche Google Central) — the render queue, “not all bots can run JavaScript,” and the History API guidance.
- SvelteKit SEO: Votre Secret Weapon (Okupter) — a practitioner guide covering meta tags, prerendering, rendering modes, données structurées, and sitemaps.
- SvelteKit SEO: Moteur de recherche Optimization Metadata (Rodney Lab) — the essential meta tags, an SEO component pattern, social cards, and language declaration.
- How to ajouter a basic SEO component to SvelteKit (Thilo Maier) — a code-focused walkthrough of a reusable SEO component.
- Creating a Sitemap in SvelteKit (Bryan Anthonio) — a clair, current guide to the
+server.jssitemap-endpoint approach. - Rich Harris explique pourquoi SvelteKit pushes pour SSR (DEV Community) — context on pourquoi SvelteKit’s creator made SSR the par défaut and pushes contre SPA/CSR.
Journal des modifications
Mis à jour le 18 juil. 2026.
Résumé éditorial et détails enregistrés des changements.Détails des changements
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
Comparaison complète indisponible — aucun instantané antérieur n’a été archivé pour cette révision.