SvelteKit Deployment SEO: Adapters, Prerendering, dan Edge rendering

SvelteKit's adapter dan per-route prerender settings decide di mana dan ketika Anda halaman render — dan itu drives TTFB, LCP, dan anggaran crawling. sebuah deployment-focused deep dive: choosing adapter-static/node/vercel/cloudflare/netlify, prerender = benar/salah/'auto', edge-runtime constraints, dan membangun sitemap.xml dan robots.txt.

Pertama kali diterbitkan: 3 Jul 2026 · Terakhir diperbarui: 3 Agu 2026 · Lanjutan

SvelteKit's adapter dan per-route prerender setting decide di mana dan ketika sebuah halaman renders — static HTML di bangun time, SSR pada sebuah server, atau SSR di edge — dan itu decision drives TTFB, yang feeds LCP dan crawl capacity. Pick adapter-static untuk pure konten situs, sebuah node/vercel/cloudflare adapter dengan per-route prerender untuk mixed konten-plus-app situs, dan sebuah edge adapter ketika global TTFB penting (accepting cold dimulai dan Tidak Node fs). prerender = 'auto' adalah mixed-situs alat. Edge runtimes dapat't baca filesystem. dan SvelteKit generates Tidak sitemap.xml atau robots.txt — Anda bangun itu sebagai +server.js endpoints, dengan strategy depending pada Anda adapter.

TL;DR — adapter tidak perubahan apa SvelteKit renders — ini perubahan di mana dan ketika: bangun-time static (adapter-static), permintaan-time pada sebuah server Anda jalankan (adapter-node), atau permintaan-time pada serverless/edge functions (adapter-vercel/-netlify/-cloudflare). Per-route prerender = true membangun static HTML dan drops route dari dynamic manifest; prerender = 'auto' prerenders dan mempertahankan ini di manifest — alat untuk mixed /blog/[slug] situs. Edge runtimes jalankan pada V8 isolates: Tidak Node fs, dan cold dimulai hurt TTFB, yang feeds LCP dan (per Google’s crawl-budget doc) crawl capacity. SvelteKit generates Tidak sitemap.xml atau robots.txt — bangun them sebagai +server.js endpoints, dan note strategy bergantung pada adapter. ini adalah sebuah lebih sempit, deployment-focused companion untuk SvelteKit SEO fundamentals artikel di ini bagian; I assume Anda sudah know SvelteKit adalah SSR-oleh-default dan tidak akan re-litigate itu di sini.

satu idea itu membuat semua dari ini click

adapter melakukan tidak perubahan apa renders. ini perubahan di mana dan ketika. itu’s seluruh hal. SvelteKit docs put ini precisely: adapters “take itu built app sebagai input dan generate output untuk deployment.” (terjemahan) “take dibangun app sebagai input dan generate output untuk deployment.” Bukti untuk klaim ini SvelteKit adapters take the built application as input and generate deployment-specific output. Cakupan: Deployment output; adapter choice can still constrain supported runtime features. Tingkat keyakinan: tinggi · Diverifikasi: SvelteKit: Adapters Anda components, Anda load functions, Anda <svelte:head> metadata — identical di seluruh setiap adapter. Apa differs adalah:

  • Ketika HTML adalah produced: di bangun time (static/prerendered) atau di permintaan time (SSR pada sebuah server, serverless function, atau edge function).
  • Di mana ini adalah produced: pada sebuah single origin server, pada sebuah regional serverless function, atau pada sebuah edge network close untuk pengunjung.

Semuanya di bawah adalah sebuah consequence dari itu dua axes.

Mengapa deployment choices adalah SEO choices

chain adalah pendek dan well-terdokumentasi: TTFB → LCP → crawl capacity.

Time untuk pertama Byte adalah bagaimana panjang host takes untuk mulai sending respons. sebuah prerendered file disajikan dari sebuah CDN cache memiliki sebuah near-zero TTFB. sebuah server itu memiliki untuk render halaman memiliki sebuah lebih tinggi satu. sebuah cold-starting serverless atau edge function dapat memiliki sebuah banyak lebih tinggi satu pada pertama hit. TTFB adalah sebuah direct input untuk Largest Contentful Paint — Anda dapat’t paint apa Anda haven’t diterima — dan LCP adalah sebuah Core Web Vitals sinyal.

crawl side adalah di mana Google adalah sebagian besar jelas. dari crawl-budget documentation: “Jika itu site responds quickly untuk a sementara, itu limit goes up, meaning lebih connections dapat menjadi digunakan untuk crawl. Jika itu site slows down atau responds dengan kesalahan server, itu limit goes down dan Google crawls lebih sedikit.” (terjemahan) “jika situs responds quickly untuk sebuah sementara, limit goes up, meaning lebih connections dapat menjadi digunakan untuk crawl. jika situs slows down atau responds dengan kesalahan server, limit goes down dan Google melakukan crawl lebih sedikit.” dan best-practice line: “Membuat Anda halaman efficient untuk load. Jika Google dapat load dan render Anda halaman lebih cepat, we mungkin menjadi able untuk baca lebih konten dari Anda site.” (terjemahan) “membuat Anda halaman efficient untuk muat. jika Google dapat muat dan render Anda halaman lebih cepat, kami mungkin menjadi able untuk baca selengkapnya konten dari Anda situs.” sebuah cold-starting edge function itu’s slow untuk respond adalah subject untuk yang sama dynamic sebagai sebuah origin yang lambat server.

«One honesty note up front: Google publishes no SvelteKit-specific guidance. There’s no doc or Search Off the Record episode naming SvelteKit adapters, prerender = 'auto', or edge cold starts. What I’m doing here is applying Google’s general rendering and crawl-budget guidance to SvelteKit’s specific mechanics — not quoting a rep who commented on SvelteKit, because none has. The Google framing that “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” is the closest official anchor, and it’s framework-agnostic. » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian dua puluh tujuh, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

Choosing sebuah adapter untuk SEO outcomes

adapter-auto — zero-config default, dan -nya ceiling

baru SvelteKit projects ship dengan adapter-auto. ini detects platform — Vercel, Netlify, Cloudflare halaman, Azure, AWS — dan installs matching adapter di bangun time. ini adalah sebuah fine starting poin, tetapi ada sebuah hard ceiling worth knowing: adapter-auto melakukan tidak take apa pun options. moment Anda perlu { edge: true }, Cloudflare bindings, Vercel ISR, atau apa pun platform-spesifik configuration, Anda install underlying adapter (adapter-vercel, adapter-cloudflare, dan seterusnya.) secara langsung. Treat auto sebagai sebuah scaffold, tidak sebuah production decision.

adapter-static — penuh SSG, untuk konten-pertama situs

adapter-static prerenders Anda seluruh situs untuk static files di bangun time. Tidak server berjalan; sebuah host menyajikan flat HTML. Bukti untuk klaim ini adapter-static prerenders a SvelteKit site as static files. Cakupan: Routes must be prerenderable; performance outcomes depend on hosting and page design. Tingkat keyakinan: tinggi · Diverifikasi: SvelteKit: Static site generation untuk sebuah konten-pertama situs ini adalah strongest SEO profile Anda dapat memiliki — lowest TTFB, Tidak cold dimulai, tidak ada apa pun untuk fall di atas. satu requirement adalah trap covered di length di fundamentals artikel: SSR harus stay pada selama bangun, atau Anda mendapatkan empty shells alih-alih dirender HTML. I tidak akan re-jelaskan itu di sini beyond flagging ini.

catch adalah rigidity. Apa pun itu genuinely perlu server logic per permintaan (benar penelusuran, per-pengguna konten, form menangani tanpa sebuah ketiga-party endpoint) dapat’t langsung pada sebuah purely static bangun — yang adalah persis apa berikutnya adapters adalah untuk.

adapter-node — sebuah server Anda control

adapter-node produces sebuah standalone Node.js server. Anda jalankan ini, Anda scale ini, Anda own TTFB. ini adalah paling flexible option dan satu dengan fewest runtime surprises — penuh Node APIs, including fs. ini adalah sebuah baik fit ketika Anda memiliki infrastructure sudah, perlu Node libraries itu edge runtimes dapat’t jalankan, atau ingin predictable (non-cold-starting) respons times dari sebuah warm server. tradeoff adalah operational: Anda’re berjalan sebuah server, dan -nya speed dan uptime adalah now Anda crawl capacity.

adapter-vercel — serverless, edge, dan ISR

adapter-vercel deploys untuk Vercel’s serverless functions oleh default, dengan several SEO-relevant levers set per route melalui export const config:

  • runtime: 'edge' moves itu route untuk Vercel’s edge runtime (lebih di bawah).
  • regions controls di mana serverless functions jalankan — closer untuk Anda pengguna (atau Anda database) berarti lebih rendah latency.
  • isr enables Incremental Static Regeneration: isr: { expiration: 60 } menyajikan sebuah cached static asset dan regenerates ini setelah window, giving “itu performance dan cost advantages dari prerendered konten dengan itu flexibility dari dynamically dirender konten.” (terjemahan) “ performa dan cost advantages dari prerendered konten dengan flexibility dari dynamically dirender konten.” ISR adalah sebuah genuine fourth path antara pure-static dan pure-SSR — tetapi note docs’ own caveat: “Menggunakan ISR pada a route dengan export const prerender = true akan memiliki Tidak effect, since itu route adalah prerendered di build time.” (terjemahan) “menggunakan ISR pada sebuah route dengan tidak terdefinisi akan memiliki Tidak effect, since route adalah prerendered di bangun time.” ISR dan prerender adalah alternatives, tidak stackable.

adapter-cloudflare — Workers/halaman, global edge

«adapter-cloudflare targets Cloudflare Workers and Pages — SSR on a global edge network, often the lowest TTFB for a geographically spread audience. The important constraint is the runtime: Workers run on V8 isolates, not Node. From the docs: “You can’t use fs in Cloudflare Workers.” Some Node APIs work only behind the nodejs_compat compatibility flag, and even then support isn’t one-to-one. If you were reading files at request time (a redirect map, a data file, custom OG-image inputs), that code needs a rethink — covered in the edge section below. » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian empat puluh, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

( older adapter-cloudflare-workers adalah deprecated; baru projects gunakan adapter-cloudflare, yang menangani keduanya Workers dan halaman. jika Anda’re pada old satu, migrating adalah recommended path.)

adapter-netlify — functions atau Edge Functions (Deno)

adapter-netlify deploys untuk Netlify’s Node-based functions oleh default, atau untuk Deno-based Edge Functions dengan edge: true. sama shape sebagai Vercel: default serverless dengan sebuah edge opt-di. Satu SvelteKit-spesifik footnote — Netlify Forms memerlukan form’s halaman untuk menjadi prerendered so Netlify dapat detect form markup di deploy time, yang adalah sebuah kecil “prerender ini route” (terjemahan) “prerender ini route” requirement layered pada top dari adapter pilihan.

decision, di satu line setiap

  • Pure konten situsadapter-static, prerender semuanya.
  • konten situs dengan dynamic pocketsadapter-node/-vercel/-cloudflare, prerender = true pada konten, false/'auto' pada dynamic routes.
  • App/dashboard dengan personalization → SSR-pertama (node atau edge), prerender hanya static shell (marketing, login).
  • Global, TTFB-critical audience → sebuah edge adapter untuk dynamic routes, accepting Node-API constraints dan cold-mulai reality.

( Decision Tree tab walks ini sebagai sebuah branching flow.)

Prerendering strategy untuk mixed situs

Apa true / false / 'auto' sebenarnya melakukan

export const prerender adalah sebuah per-route (atau per-layout) halaman option, dan three nilai tidak hanya pada/off:

  • true — bangun ini route untuk static HTML di bangun time. Critically, ini adalah “excluded dari manifests digunakan untuk dynamic SSR, membuat Anda server (atau serverless/edge functions) lebih kecil.” (terjemahan) “excluded dari manifests digunakan untuk dynamic SSR, membuat Anda server (atau serverless/edge functions) lebih kecil.” Setelah prerendered, route dapat’t fall back untuk dynamic rendering — ini adalah static, penuh berhenti.
  • false — selalu render pada permintaan. Tidak static file.
  • 'auto' — mixed-situs alat. ini prerenders route dan mempertahankan ini di dynamic server manifest, so yang sama route dapat menjadi disajikan statically untuk known paths dan server-dirender untuk rest. ini adalah dibangun untuk persis case docs deskripsikan: sebuah route like /blog/[slug] “di mana Anda ingin untuk prerender Anda paling recent/popular konten tetapi server-render itu long tail.” (terjemahan) “di mana Anda ingin prerender Anda sebagian besar recent/popular konten tetapi server-render panjang tail.”

Karena prerendered routes shrink server bundle, sebuah mostly-prerendered situs dengan sebuah sedikit 'auto'/false routes deploys sebuah lebih kecil, cheaper, lebih cepat function — sebuah efficiency win independent dari SEO.

Dynamic routes perlu sebuah entries function

prerender crawler discovers halaman oleh berikut <a> tautan dari Anda entry poin. itu berfungsi untuk static routes, tetapi sebuah dynamic route like /blog/[slug] memiliki Tidak fixed URL untuk crawler untuk temukan. jika tidak ada apa pun tautan untuk sebuah diberikan slug, SvelteKit tidak akan know ini ada — dan Anda’ll hit classic bangun error itu routes “adalah marked sebagai prerenderable, tetapi adalah tidak prerendered.” (terjemahan) “adalah marked sebagai prerenderable, tetapi adalah tidak prerendered.”

perbaiki adalah sebuah jelas entries function (atau config.kit.prerender.entries) itu enumerates parameter nilai:

// src/routes/blog/[slug]/+page.server.js
export const prerender = true;

export function entries() {
  return [
    { slug: 'hello-world' },
    { slug: 'sveltekit-deployment-seo' },
  ];
}

dalam praktik Anda generate itu list dari Anda CMS atau konten directory. Tanpa ini, prerendering hanya covers slugs tautan crawler happens untuk temukan.

/blog/[slug] pattern di wild

Put dua together dan Anda memiliki canonical mixed-situs setup: prerender = 'auto' plus sebuah entries function itu mengembalikan Anda recent dan popular posts. itu mendapatkan static HTML di bangun time; apa pun tidak di list falls melalui untuk SSR pada demand. baru posts render dynamically until berikutnya bangun prerenders them. ini adalah pragmatis middle ground antara “prerender all 40,000 posts setiap build” (terjemahan) “prerender semua 40 000 posts setiap bangun” dan “render every post on every request.” (terjemahan) “render setiap post pada setiap permintaan.”

Edge runtime constraints itu memengaruhi SEO

config.runtime = 'edge' adalah per-route (pada Vercel)

Edge tidak sebuah semua-atau-tidak ada apa pun switch. pada Vercel ini adalah sebuah per-route halaman option:

// +page.server.js or +server.js
export const config = { runtime: 'edge' };

itu berarti Anda dapat push tinggi-traffic, cacheable routes untuk edge untuk rendah TTFB sementara mempertahankan Node-dependent routes pada standard serverless (Node) runtime di yang sama deployment. Mix dengan sengaja.

Tidak fs, Tidak arbitrary Node APIs

«The edge runtimes — Cloudflare Workers, Vercel Edge Functions, Netlify’s Deno Edge Functions — don’t provide Node’s fs. Cloudflare’s docs: “You can’t use fs in Cloudflare Workers.” Vercel’s: “You can’t use fs in edge functions.” Both point to the same two escape hatches: use the read helper from $app/server to access bundled assets, or “prerender the routes in question” so the file access happens at build time instead of at request time. » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian enam puluh lima, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

SEO-berdekatan cases di mana ini bites: dynamic OG-image generation itu membaca sebuah font atau template file, file-based redirect maps, atau sebuah sitemap endpoint itu membaca konten off disk. apa pun dari itu either moves untuk $app/server’s read() atau moves untuk prerender/bangun time. ini adalah tidak sebuah blocker — ini adalah sebuah “know before you pick edge” (terjemahan) “know sebelum Anda pick edge” constraint.

Cold dimulai dan TTFB — ketika edge helps dan ketika ini tidak

Edge functions masih cold-mulai. sebuah cold edge function pada -nya pertama permintaan dapat menjadi lebih lambat daripada sebuah warm Node server, dan dramatically lebih lambat daripada sebuah prerendered file disajikan dari cache. Edge wins ketika function tetap warm atau ketika ini adalah paired dengan aggressive caching so sebagian besar permintaan tidak pernah hit function di semua. ini adalah tidak secara otomatis fastest option — “deploy to the edge” (terjemahan) “deploy untuk edge” adalah tidak sebuah synonym untuk “lebih cepat.” (terjemahan) “lebih cepat.” untuk sebuah konten situs, prerendered static output beats edge SSR pada TTFB setiap time, karena ada Tidak function untuk mulai.

Generating sitemap.xml dan robots.txt (SvelteKit tidak akan)

ini adalah kesenjangan sebagian besar SvelteKit tutorials skip dan sebagian besar audits catch. SvelteKit generates Tidak sitemap.xml dan Tidak robots.txt secara otomatis — regardless dari adapter, regardless dari bagaimana banyak halaman Anda prerender. sebuah fully static situs dengan thousands dari prerendered halaman masih ships dengan Tidak sitemap unless Anda bangun satu.

+server.js endpoint pattern

idiomatic sitemap adalah sebuah route endpoint itu mengembalikan XML dengan right Content-Type:

// src/routes/sitemap.xml/+server.js
export const prerender = true; // needed on adapter-static

export async function GET() {
  const urls = await getAllUrls(); // from your CMS/content
  const body = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map((u) => `  <url><loc>${u}</loc></url>`).join('\n')}
</urlset>`;

  return new Response(body, {
    headers: { 'Content-Type': 'application/xml' },
  });
}

strategy bergantung pada Anda adapter

Di sini’s bagian itu ties ini seluruh artikel together: Anda sitemap strategy adalah downstream dari Anda adapter pilihan.

  • pada adapter-static, sitemap endpoint perlu export const prerender = benar so ini adalah disertakan di static output — ada Tidak server di runtime untuk generate ini pada permintaan. ini adalah baked di bangun time, yang berarti ini adalah hanya sebagai fresh sebagai Anda terakhir bangun.
  • pada sebuah Node/serverless/edge adapter, yang sama endpoint dapat generate sitemap dynamically per permintaan dari Anda CMS atau database — selalu saat ini, Tidak rebuild needed. (pada sebuah edge adapter, remember fs constraint: pull URLs dari sebuah API atau binding, tidak sebuah disk baca.)

So “should my sitemap be static or dynamic?” (terjemahan) “seharusnya my sitemap menjadi static atau dynamic?” pertanyaan tidak sebuah terpisah decision — ini falls out dari adapter Anda sudah chose.

«### robots.txt: static file vs. endpoint » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian tujuh puluh delapan, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

Dua options. Drop sebuah plain robots.txt di Anda static/ folder (disajikan di /robots.txt secara otomatis), yang adalah simplest pilihan dan fine untuk sebagian besar situs. atau generate ini dari sebuah src/routes/robots.txt/+server.js endpoint ketika Anda perlu ini untuk differ oleh environment (blocking crawler pada staging, allowing them di production, misalnya). Either cara, jangan block Anda /_app/ bundle atau CSS — itu breaks rendering untuk mesin itu melakukan render.

jika Anda’re coming di ini dari lebih luas kerangka kerja atau JavaScript-SEO angle, “where and when does rendering happen” (terjemahan) “di mana dan ketika melakukan rendering happen” logic di sini adalah yang sama logic itu governs JavaScript SEO umumnya, dan SvelteKit fundamentals piece di ini bagian covers rendering modes dan metadata patterns ini artikel membangun pada top dari.

Tambahkan catatan pakar

Sematkan kutipan pakar

Orang baru? Buat profilnya yang belum diklaim di /admin/experts/ → Sematkan kutipan pakar terlebih dahulu.