Panduan Svelte SEO

Svelte alone adalah client-side rendered — konten isn't di raw HTML. SvelteKit fixes itu dengan SSR oleh default. rendering modes, svelte:head, muat functions, adapters, sitemaps, dan SPA-mode trap.

Pertama kali diterbitkan: 26 Jun 2026 · Terakhir diperbarui: 3 Agu 2026 · Advanced
Bahasa

Svelte SEO hinges pada one distinction: plain Svelte adalah client-side rendered (sebuah blank HTML shell), while SvelteKit renders pada server oleh default dan ships full HTML. gunakan SvelteKit untuk anything itu perlu untuk peringkat. Manage metadata dengan svelte:head, fetch SEO data di +halaman.server.js muat functions, pick right adapter, dan tidak pernah ship SPA fallback mode (ssr: salah) — SvelteKit docs themselves warn ini memiliki besar negative SEO impacts.

TL;DR — Svelte SEO adalah really sebuah SvelteKit conversation. Bare Svelte adalah CSR-hanya — konten isn’t di raw HTML. SvelteKit defaults untuk SSR, mendukung prerendering (SSG) per route, dan lets Anda mix modes. Manage metadata dengan <svelte:head> dan feed ini dari +page.server.js muat functions so ini lands di initial HTML. sharpest trap: adapter-static dengan ssr: false melakukan not prerender — ini produces empty shells; SSR harus stay pada selama bangun. SvelteKit’s own docs warn SPA fallback memiliki “large negative performance and SEO impacts.” (terjemahan) “besar negative performa dan SEO impacts.” gunakan History API routing ( default), configure trailingSlash, dan pick sebuah adapter untuk match — static untuk konten, node/vercel/cloudflare untuk SSR.

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 Guide

Svelte adalah not SvelteKit — dan untuk SEO itu’s everything

Svelte adalah sebuah compiler. ini turns Anda .svelte components ke lean vanilla JavaScript dengan no virtual DOM dan no runtime library shipped untuk browser. itu gives Svelte sebuah nyata performa edge — tetapi ini adalah sebuah bundle-size optimization, not sebuah rendering one. sebuah plain Svelte app (Vite-bundled, no meta-framework) adalah masih sebuah client-side-rendered SPA: server mengembalikan sebuah blank HTML shell dan browser constructs halaman. View source pada one dan Anda konten isn’t there.

ini adalah #1 source dari confusion when people search “Svelte SEO.” (terjemahan) “Svelte SEO.” compile langkah doesn’t put konten di HTML. SvelteKit melakukan. SvelteKit adalah Svelte’s official meta-framework — equivalent dari Next.js untuk React atau Nuxt untuk Vue — dan ini renders halaman pada server oleh default, shipping fully populated HTML sebelum apa pun JavaScript runs. ini menambahkan SSR, static prerendering, file-based routing, muat functions, dan deployment adapters. headline: bare Svelte = CSR-hanya; SvelteKit = SSR-pertama. Everything else di ini guide assumes SvelteKit.

Two scoping notes worth stating precisely, because mereka’re where generic “Svelte SEO” (terjemahan) “Svelte SEO” advice goes wrong: SvelteKit’s rendering options (ssr, csr, prerender, trailingSlash) adalah set per route dan inherit hierarchically — sebuah +layout.js atau +layout.server.js dapat set sebuah default untuk everything beneath ini, dan sebuah child route dapat override ini. So “is this SvelteKit site SEO-friendly” (terjemahan) “adalah ini SvelteKit situs SEO-friendly” isn’t sebuah project-tingkat pertanyaan; periksa spesifik route. dan dari SvelteKit’s rendering options, ini adalah specifically ssr: false — not SSR menjadi merely absent, dan not “using SvelteKit” (terjemahan) “menggunakan SvelteKit” di umum — itu docs tie untuk sebuah empty output: “If you set ssr to false, it renders an empty ‘shell’ page instead.” (terjemahan) “jika Anda set undefined untuk undefined, ini renders sebuah empty ‘shell’ halaman instead.” ini guide adalah saat ini untuk Svelte 5.x dan SvelteKit 2.x ( saat ini majors sebagai dari ini update); Svelte 5 dibuat runes default reactivity model, tetapi runes adalah sebuah component-authoring concern, not sebuah rendering mode — mereka don’t perubahan apa pun dari SEO guidance below.

Why rendering mode penting comes straight dari how mesin pencari berfungsi. Google processes JavaScript di three phases — crawling, rendering, dan pengindeksan — dan “all pages with a 200 HTTP status code are sent to the rendering queue, no matter whether JavaScript is present on the page.” (terjemahan) “semua halaman dengan sebuah undefined HTTP kode status adalah dikirim untuk rendering queue, no penting whether JavaScript adalah present pada halaman.” render queue menambahkan sebuah delay, dan sebagai Google’s own guidance puts ini, “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.” (terjemahan) “server-side atau pre-rendering adalah masih sebuah great idea because ini membuat Anda situs web faster untuk pengguna dan crawler, dan not semua bot dapat run JavaScript.” itu last clause adalah doing sebuah lot dari berfungsi di 2026 — see AI-crawler bagian.

four rendering modes di SvelteKit

SvelteKit’s strength adalah itu rendering adalah sebuah per-route decision via halaman options. ini options adalah hierarchical: set sebuah default di sebuah +layout.js/+layout.server.js dan setiap nested route inherits ini, unless sebuah child route exports -nya own nilai untuk override ini. periksa option itu actually applies untuk spesifik route Anda care tentang — not hanya nilai set di top dari project.

  • SSR ( default). halaman adalah rendered server-side dan full HTML adalah di initial respons. Best untuk dynamic, personalized, atau frequently changing konten. ini adalah pada unless Anda turn ini off.
  • Prerender (export const prerender = true). halaman adalah generated sebagai static HTML di bangun time. Maximum speed dan maximum crawlability — ideal untuk blog posts, docs, dan marketing halaman. Crucially, prerendering adalah SSR run di bangun time, so SSR harus remain enabled untuk ini untuk berfungsi.
  • SPA fallback (ssr: false). sebuah single-halaman-app shell dengan no server rendering. SvelteKit docs adalah blunt itu ini mode “has large negative performance and SEO impacts” (terjemahan) “memiliki besar negative performa dan SEO impacts” dan adalah really dimaksudkan untuk things like wrapping di sebuah mobile app — not untuk konten Anda ingin terindeks.
  • Hybrid. Mix modes per route: prerender Anda marketing halaman, SSR Anda product halaman, run sebuah SPA-style admin behind sebuah login. ini adalah SvelteKit’s killer fitur — Anda tidak pick one rendering mode untuk whole situs.

ssr: false trap ( mistake untuk hindari)

ini adalah paling expensive misunderstanding di SvelteKit SEO, so ini gets -nya own bagian. People reach untuk adapter-static untuk “make a static site,” (terjemahan) “membuat sebuah static situs,” dan lalu set ssr: false thinking mereka’re getting prerendered HTML. mereka aren’t.

Prerendering adalah rendering sisi server executed di bangun time. jika Anda disable SSR, ada nothing untuk render — docs adalah explicit itu ssr: false “renders an empty ‘shell’ page instead,” (terjemahan) “renders sebuah empty ‘shell’ halaman instead,” dan itu’s exactly what adapter-static lalu ships sebagai Anda prerendered output. konten hanya appears once client-side JavaScript runs, which puts Anda right back di CSR territory (dengan semua -nya crawler masalah) despite having sebuah “static” (terjemahan) “static” bangun. aturan: dengan adapter-static, leave ssr pada (-nya default) so prerendering outputs nyata HTML. gunakan ssr: false hanya when Anda genuinely ingin sebuah SPA shell dan accept SEO cost.

Managing metadata dengan <svelte:head>

SvelteKit memiliki sebuah special element, <svelte:head>, itu injects konten ke document <head> — dan Anda tidak perlu sebuah ketiga-party library untuk manage Anda judul dan meta tags. setiap halaman seharusnya memiliki sebuah unique <title> dan <meta name="description">, plus canonical, Open Graph, Twitter Card, hreflang, robots directives, dan JSON-LD sebagai needed.

pattern official docs recommend untuk dynamic metadata:

  1. kembalikan SEO metadata dari sebuah +page.server.js load() function.
  2. Access ini via page.data di Anda layout.
  3. Render ini di <svelte:head> di 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>

jika Anda’d rather gunakan component wrapper, ketiga-party svelte-seo package wraps <svelte:head> dengan props untuk umum tags — tetapi ini adalah sebuah convenience, not sebuah requirement.

<svelte:head> gets Anda tags ke head; ini doesn’t verify Anda got them right. itu’s masih Anda job: confirm setiap route renders sebuah unique judul dan deskripsi (not one inherited dari layout oleh accident), itu canonical Anda emit adalah consistent antara direct-permintaan HTML dan what sebuah client-side navigation renders, dan itu robots directives dan JSON-LD adalah present di raw respons — not hanya terlihat setelah hydration.

muat functions: where Anda fetch SEO data penting

ini adalah metadata bug itu bites people. +page.server.js load() runs pada server, so -nya data adalah di initial HTML respons. +page.js load() runs pada server untuk pertama render dan pada client selama client-side navigation. mistake adalah fetching Anda judul/deskripsi/canonical di sebuah <script> block dengan onMount() — itu runs client-side hanya, so initial HTML ships dengan no metadata dan crawler sees nothing pada pertama fetch. Fetch SEO-critical data di sebuah load function (server muat untuk anything itu harus menjadi di pertama respons), not di onMount.

Don’t assume file name alone proves boundary, though — +page.js load() juga runs pada server untuk pertama permintaan, lalu re-runs client-side pada navigation, dan -nya kembalikan nilai memiliki untuk survive serialization untuk menjadi reused safely pada client. jika SEO-critical data ever depends pada sebuah nilai itu isn’t safely serializable, verify both direct-permintaan HTML dan sebuah client-navigated view dari yang sama route, not hanya one atau lainnya.

Routing dan struktur URL

  • File-based routing dengan [param] untuk dynamic segments gives Anda clean, predictable URLs.
  • History API routing adalah default — SvelteKit doesn’t gunakan hash/fragment routing, dan itu’s exactly what Anda ingin. Google dapat’t reliably resolve hash-based (#/page) URLs, so History API routing adalah SEO-safe choice dan SvelteKit membuat ini default.
  • trailingSlash di svelte.config.js accepts 'always', 'never', atau 'ignore'. SvelteKit handles canonical redirect untuk Anda, tetapi leaving ini misconfigured (terutama 'ignore') dapat buat duplicate-konten variants. Pick one dan menjadi consistent.
  • Dynamic routes Anda ingin prerendered perlu sebuah entries function untuk enumerate paths di bangun time, atau SvelteKit won’t know which URLs untuk generate.

Choosing sebuah adapter untuk SEO

adapter decides how dan where Anda SvelteKit app adalah deployed, dan itu memiliki SEO consequences (mostly via TTFB, which feeds LCP):

AdapterrenderingSEO implication
adapter-staticFull SSGbenar static HTML untuk setiap halaman; no server needed; ideal untuk konten-heavy situs (pertahankan ssr pada!)
adapter-nodeSSR pada sebuah Node serverDynamic SSR, full flexibility; Anda run sebuah server
adapter-vercelSSR + edgeSSR dengan optional edge functions; edge TTFB helps LCP
adapter-cloudflareSSR pada WorkersEdge SSR globally — potentially fastest TTFB/LCP
adapter-netlifySSR + CDNSimilar profile untuk Vercel

untuk sebuah blog atau docs situs, adapter-static dengan prerendering gives Anda maximum speed dan crawlability. untuk dynamic situs, adapter-cloudflare atau adapter-vercel put SSR di edge, which dapat shrink TTFB dan help Largest Contentful Paint — tetapi adapter hanya picks deployment shape. Actual TTFB depends pada Anda data fetching, caching, dan runtime’s cold-start perilaku, so mengukur deployed halaman rather daripada assuming adapter alone delivers win.

sebuah adapter adalah sebuah boundary, not hanya sebuah deploy target: streaming, filesystem, caching, edge/runtime APIs, redirects, dan error handling dapat semua behave differently antara adapters. sebuah route itu looks correct dengan local dev server atau adapter-node isn’t guaranteed untuk behave identically once deployed melalui adapter-cloudflare atau adapter-vercel — test production bangun pada actual target, not hanya npm run preview.

Sitemaps dan robots.txt

SvelteKit memiliki no dibangun-di sitemap atau robots.txt — like sebuah headless setup, Anda bangun them explicitly.

  • Sitemap, manual: buat src/routes/sitemap.xml/+server.js itu mengembalikan XML. tambahkan export const prerender = true jika Anda’re pada adapter-static.
  • Sitemap, dynamic: sebuah server-rendered endpoint itu kueri Anda CMS/database dan mengembalikan fresh XML pada setiap permintaan — best untuk besar atau fast-changing situs.
  • Sitemap, packages: svelte-sitemap scans routes post-bangun (untuk SSG), dan sveltekit-static-sitemap generates dari prerendered routes.
  • robots.txt: drop sebuah static file di static/ (disajikan di /robots.txt automatically) atau generate ini dari sebuah src/routes/robots.txt/+server.js endpoint. Whichever Anda choose, don’t block Anda .js/.css — Google won’t render dari blocked files.

performa dan Core Web Vitals

SvelteKit’s compiler dan framework mechanics give Anda sebuah structural head start pada performa, dan Core Web Vitals adalah sebuah peringkat input — tetapi mechanics themselves don’t guarantee sebuah score. compiler outputs vanilla JS dengan no virtual DOM dan no runtime library, so sebuah typical SvelteKit halaman ships less JavaScript daripada sebuah equivalent React-based app; automatic per-route code splitting, dibangun-di asset dan tautan preloading, file-hashing untuk panjang-lived caching, dan edge deployment via several adapters adalah semua available. What Anda bangun dengan itu mechanics — halaman weight, image handling, ketiga-party scripts, hydration cost, dan deployment target Anda actually choose — masih decides Anda diukur CWV dan Anda rankings. Treat framework sebagai menghapus obstacles, not sebagai delivering hasil. SvelteKit docs poin Anda di right pengukuran alat: “Google’s PageSpeed Insights and WebPageTest are excellent ways to understand the performance characteristics of a site.” (terjemahan) “Google’s PageSpeed Insights dan WebPageTest adalah excellent cara untuk memahami performa characteristics dari sebuah situs.” Image optimization adalah available via @sveltejs/enhanced-img.

AI crawler dan SSR imperative

Here’s 2026 wrinkle older SvelteKit SEO guides miss. rendering perilaku untuk GPTBot (OpenAI), ClaudeBot (Anthropic), PerplexityBot, dan Bingbot fetch behind Copilot adalah provider- dan versi-spesifik, dan saat ini provider documentation doesn’t establish one shared render langkah Anda dapat rely pada. Treat “generally fetches static HTML without executing JavaScript” (terjemahan) “umumnya fetches static HTML without executing JavaScript” sebagai safe planning assumption, not sebuah guarantee tentang setiap provider forever. sebuah CSR route (bare Svelte, atau SvelteKit dengan ssr: false) ships setiap one dari ini crawler yang sama empty shell sebuah pertama-fetch Googlebot permintaan sees; SvelteKit’s default SSR puts Anda konten di raw HTML so no crawler memiliki untuk depend pada sebuah render langkah di semua. itu’s argument untuk keeping SSR pada untuk anything Anda ingin AI sistem untuk see — not sebuah promise itu SSR guarantees inclusion di sebuah AI jawaban, which depends pada factors well beyond rendering.

umum SvelteKit SEO mistakes

  • Fetching SEO data di onMount() alih-alih sebuah server muat function — metadata isn’t di initial HTML.
  • Shipping SPA fallback mode (ssr: false) untuk konten Anda ingin diperingkatkan.
  • adapter-static dengan ssr: false — empty shells, not prerendered halaman.
  • Blocking JS/CSS di robots.txt — breaks rendering.
  • Skipping trailingSlash configuration — duplicate-konten variants.
  • menggunakan hash/fragment routing — Googlebot dapat’t resolve itu URLs (SvelteKit’s History API default sudah protects Anda here).

jika Anda’re coming di ini dari broader framework angle, Svelte/SvelteKit adalah one dari decoupled frontends sebuah CMS headless pairs dengan, dan rendering-mode logic here adalah yang sama logic itu governs JavaScript SEO umumnya — itu topics live alongside ini one di cluster.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.