SvelteKit Deployment SEO: Adapters, Prerendering, dan Edge rendering
SvelteKit's adapter dan per-route prerender settings decide where dan when 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.
Bahasa
SvelteKit's adapter dan per-route prerender setting decide where dan when sebuah halaman renders — static HTML di bangun time, SSR pada sebuah server, atau SSR di edge — dan itu decision drives TTFB, which 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 when global TTFB penting (accepting cold starts dan no Node fs). prerender = 'auto' adalah mixed-situs alat. Edge runtimes dapat't read filesystem. dan SvelteKit generates no sitemap.xml atau robots.txt — Anda bangun itu sebagai +server.js endpoints, dengan strategy depending pada Anda adapter.
TL;DR — SvelteKit sudah renders Anda halaman pada server — itu bagian adalah handled. ini halaman adalah tentang next decision: how Anda situs gets dibangun dan deployed. sebuah adapter packages Anda SvelteKit app untuk sebuah host (sebuah static file host, sebuah Node server, atau sebuah service like Vercel atau Cloudflare), dan sebuah per-halaman prerender setting decides whether sebuah halaman adalah turned ke sebuah plain HTML file ahead dari time atau rendered fresh pada setiap visit. itu two choices decide how fast crawler get Anda HTML — dan SvelteKit won’t membuat Anda sitemap atau robots.txt, so Anda memiliki untuk tambahkan itu yourself.
What sebuah adapter adalah (di plain istilah)
jika Anda’ve sudah dibangun sebuah SvelteKit situs, Anda know ini mengirim nyata HTML untuk browser — konten adalah there sebelum apa pun JavaScript runs. baik. itu’s hard SEO masalah sudah solved (dan jika ini isn’t solved untuk Anda yet, SvelteKit fundamentals artikel di ini sama bagian covers rendering modes dan “empty shell” (terjemahan) “empty shell” trap Anda ingin hindari pertama).
sebuah adapter adalah kecil plugin itu takes Anda finished SvelteKit bangun dan turns ini ke something sebuah spesifik host dapat run. Evidence for this claim SvelteKit adapters transform a built application for deployment to a particular environment. Scope: SvelteKit adapters. Confidence: high · Verified: SvelteKit: Adapters sama situs, berbeda package:
adapter-staticturns setiap halaman ke sebuah plain HTML file, dibangun once. Great untuk sebuah blog, docs, atau sebuah marketing situs itu doesn’t perubahan per pengunjung.adapter-nodewraps Anda app di sebuah Node.js server Anda run yourself.adapter-vercel,adapter-netlify,adapter-cloudflarepackage ini untuk itu hosting services, which render halaman pada demand — sometimes pada server “at the edge,” (terjemahan) “di edge,” physically close untuk Anda pengunjung.
konten adalah identical di semua cases. What perubahan adalah when HTML adalah dibuat (ahead dari time, atau pada setiap permintaan) dan where (one server, atau sebuah global network).
Why ini adalah sebuah SEO decision, not hanya sebuah tech one
main thing: speed. sebuah halaman itu’s sudah sebuah static file memuat almost instantly. sebuah halaman itu memiliki untuk menjadi dibangun pada server takes sebuah moment. dan Google memiliki said plainly itu jika Anda situs “responds quickly for a while, the limit goes up, meaning more connections can be used to crawl. If the site slows down… the limit goes down and Google crawls less.” (terjemahan) “responds quickly untuk sebuah while, limit goes up, meaning more connections dapat menjadi digunakan untuk crawl. jika situs slows down… limit goes down dan Google melakukan crawl less.” So sebuah slow deployment doesn’t hanya annoy pengguna — ini dapat berarti Google reads less dari Anda situs.
sederhana versi dari decision
- sebuah konten situs (blog, docs, marketing) → gunakan
adapter-staticdan prerender everything. Fastest mungkin, nothing untuk break. - sebuah konten situs dengan sebuah few dynamic bits (search, comments) → gunakan server
adapter (
node/vercel/cloudflare) dan mark Anda konten halamanprerender = true, leaving dynamic bits untuk render pada permintaan. - sebuah app atau dashboard dengan logged-di, personalized halaman → render pada server (SSR), prerender hanya public marketing halaman.
Don’t forget two files SvelteKit won’t membuat untuk Anda
SvelteKit doesn’t generate sebuah sitemap.xml atau sebuah robots.txt automatically. Anda
tambahkan them yourself — biasanya sebagai sebuah kecil endpoint file (sitemap.xml/+server.js)
dan either sebuah file di Anda static/ folder atau lainnya endpoint untuk
robots.txt. Evidence for this claim SvelteKit can serve static assets from its static directory and create custom responses with +server route files. Scope: Mechanisms for robots.txt and sitemap.xml; files are not generated automatically. Confidence: high · Verified: SvelteKit: Project structure SvelteKit: Routing ini adalah easy untuk forget because sebagian besar frameworks itu render HTML untuk
Anda feel “complete.” (terjemahan) “complete.” ini two aren’t.
ingin deeper versi — what setiap adapter melakukan untuk rendering, how
prerender = 'auto' handles sebuah mixed situs, why edge functions dapat’t read files,
dan how sitemap strategy perubahan dengan Anda adapter? Switch untuk
Advanced tab.
TL;DR — adapter doesn’t perubahan what SvelteKit renders — ini perubahan where dan when: bangun-time static (
adapter-static), permintaan-time pada sebuah server Anda run (adapter-node), atau permintaan-time pada serverless/edge functions (adapter-vercel/-netlify/-cloudflare). Per-routeprerender = truemembangun static HTML dan drops route dari dynamic manifest;prerender = 'auto'prerenders dan mempertahankan ini di manifest — alat untuk mixed/blog/[slug]situs. Edge runtimes run pada V8 isolates: no Nodefs, dan cold starts hurt TTFB, which feeds LCP dan (per Google’s crawl-budget doc) crawl capacity. SvelteKit generates no sitemap.xml atau robots.txt — bangun them sebagai+server.jsendpoints, dan note strategy depends pada adapter. ini adalah sebuah narrower, deployment-focused companion untuk SvelteKit SEO fundamentals artikel di ini bagian; I assume Anda sudah know SvelteKit adalah SSR-oleh-default dan won’t re-litigate itu here.
one idea itu membuat semua dari ini click
adapter melakukan not perubahan what renders. ini perubahan where dan when.
itu’s whole thing. SvelteKit docs put ini precisely: adapters “take the
built app as input and generate output for deployment.” (terjemahan) “take
dibangun app sebagai input dan generate output untuk deployment.” Evidence for this claim SvelteKit adapters take the built application as input and generate deployment-specific output. Scope: Deployment output; adapter choice can still constrain supported runtime features. Confidence: high · Verified: SvelteKit: Adapters Anda components, Anda
load functions, Anda <svelte:head> metadata — identical di seluruh setiap adapter.
What differs adalah:
- When HTML adalah produced: di bangun time (static/prerendered) atau di permintaan time (SSR pada sebuah server, serverless function, atau edge function).
- Where ini adalah produced: pada sebuah single origin server, pada sebuah regional serverless function, atau pada sebuah edge network close untuk pengunjung.
Everything below adalah sebuah consequence dari itu two axes.
Why deployment choices adalah SEO choices
chain adalah pendek dan well-documented: TTFB → LCP → crawl capacity.
Time untuk pertama Byte adalah how panjang host takes untuk start sending respons. sebuah prerendered file disajikan dari sebuah CDN cache memiliki sebuah near-zero TTFB. sebuah server itu memiliki untuk render halaman memiliki sebuah higher one. sebuah cold-starting serverless atau edge function dapat memiliki sebuah much higher one pada pertama hit. TTFB adalah sebuah direct input untuk Largest Contentful Paint — Anda dapat’t paint what Anda haven’t diterima — dan LCP adalah sebuah Core Web Vitals signal.
crawl side adalah where Google adalah sebagian besar explicit. dari crawl-budget documentation: “If the site responds quickly for a while, the limit goes up, meaning more connections can be used to crawl. If the site slows down or responds with server errors, the limit goes down and Google crawls less.” (terjemahan) “jika situs responds quickly untuk sebuah while, limit goes up, meaning more connections dapat menjadi digunakan untuk crawl. jika situs slows down atau responds dengan server errors, limit goes down dan Google melakukan crawl less.” dan best-practice line: “Make your pages efficient to load. If Google can load and render your pages faster, we might be able to read more content from your site.” (terjemahan) “membuat Anda halaman efficient untuk muat. jika Google dapat muat dan render Anda halaman faster, 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 slow origin server.
One honesty note up front: Google publishes no SvelteKit-spesifik guidance.
There’s no doc atau Search Off Record episode naming SvelteKit adapters,
prerender = 'auto', atau edge cold starts. What I’m doing here adalah applying
Google’s umum rendering dan crawl-budget guidance untuk SvelteKit’s spesifik
mechanics — not quoting sebuah rep who commented pada SvelteKit, because none memiliki.
Google framing itu “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” adalah closest official anchor, dan ini adalah framework-agnostic.
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 there’s sebuah hard ceiling worth
knowing: adapter-auto melakukan not 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, etc.) directly. Treat auto sebagai sebuah scaffold, not sebuah production
decision.
adapter-static — full SSG, untuk konten-pertama situs
adapter-static prerenders Anda whole situs untuk static files di bangun time. No
server runs; sebuah host menyajikan flat HTML. Evidence for this claim adapter-static prerenders a SvelteKit site as static files. Scope: Routes must be prerenderable; performance outcomes depend on hosting and page design. Confidence: high · Verified: SvelteKit: Static site generation untuk sebuah konten-pertama situs ini adalah
strongest SEO profile Anda dapat memiliki — lowest TTFB, no cold starts, nothing untuk fall
di atas. one requirement adalah trap covered di length di fundamentals
artikel: SSR harus stay pada selama bangun, atau Anda get empty shells alih-alih
rendered HTML. I won’t re-jelaskan itu here beyond flagging ini.
catch adalah rigidity. Anything itu genuinely perlu server logic per permintaan (benar search, per-pengguna konten, form handling without sebuah ketiga-party endpoint) dapat’t live pada sebuah purely static bangun — which adalah exactly what next adapters adalah untuk.
adapter-node — sebuah server Anda control
adapter-node produces sebuah standalone Node.js server. Anda run ini, Anda scale ini, Anda
own TTFB. ini adalah paling flexible option dan one dengan fewest runtime
surprises — full Node APIs, including fs. ini adalah sebuah baik fit when Anda memiliki
infrastructure sudah, perlu Node libraries itu edge runtimes dapat’t run, atau ingin
predictable (non-cold-starting) respons times dari sebuah warm server. tradeoff adalah
operational: Anda’re running 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 via export const config:
runtime: 'edge'moves itu route untuk Vercel’s edge runtime (more below).regionscontrols where serverless functions run — closer untuk Anda pengguna (atau Anda database) berarti lower latency.isrenables Incremental Static Regeneration:isr: { expiration: 60 }menyajikan sebuah cached static asset dan regenerates ini setelah window, giving “the performance and cost advantages of prerendered content with the flexibility of dynamically rendered content.” (terjemahan) “ performa dan cost advantages dari prerendered konten dengan flexibility dari dynamically rendered konten.” ISR adalah sebuah genuine fourth path antara pure-static dan pure-SSR — tetapi note docs’ own caveat: “Using ISR on a route withexport const prerender = truewill have no effect, since the route is prerendered at build time.” (terjemahan) “menggunakan ISR pada sebuah route dengan undefined akan memiliki no effect, since route adalah prerendered di bangun time.” ISR dan prerender adalah alternatives, not stackable.
adapter-cloudflare — Workers/halaman, global edge
adapter-cloudflare targets Cloudflare Workers dan halaman — SSR pada sebuah global edge
network, sering lowest TTFB untuk sebuah geographically spread audience. penting
constraint adalah runtime: Workers run pada V8 isolates, not Node. dari docs:
“You can’t use fs in Cloudflare Workers.” (terjemahan) “Anda dapat’t gunakan fs di Cloudflare Workers.” beberapa Node APIs berfungsi hanya behind
nodejs_compat compatibility flag, dan bahkan lalu mendukung isn’t one-untuk-one. jika Anda
adalah reading files di permintaan time (sebuah peta pengalihan, sebuah data file, custom OG-image
inputs), itu code perlu sebuah rethink — covered di edge bagian below.
( older adapter-cloudflare-workers adalah deprecated; baru projects gunakan
adapter-cloudflare, which handles both Workers dan halaman. jika Anda’re pada old
one, 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. One SvelteKit-spesifik footnote — Netlify Forms
memerlukan form’s halaman untuk menjadi prerendered so Netlify dapat detect form markup
di deploy time, which adalah sebuah kecil “prerender this route” (terjemahan) “prerender ini route” requirement layered pada top
dari adapter choice.
decision, di one line setiap
- Pure konten situs →
adapter-static, prerender everything. - konten situs dengan dynamic pockets →
adapter-node/-vercel/-cloudflare,prerender = truepada 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-start reality.
( Decision Tree tab walks ini sebagai sebuah branching flow.)
Prerendering strategy untuk mixed situs
What true / false / 'auto' actually melakukan
export const prerender adalah sebuah per-route (atau per-layout) halaman option, dan three
nilai aren’t hanya pada/off:
true— bangun ini route untuk static HTML di bangun time. Critically, ini adalah “excluded from manifests used for dynamic SSR, making your server (or serverless/edge functions) smaller.” (terjemahan) “excluded dari manifests digunakan untuk dynamic SSR, membuat Anda server (atau serverless/edge functions) smaller.” Once prerendered, route dapat’t fall back untuk dynamic rendering — ini adalah static, full stop.false— selalu render pada permintaan. No 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-rendered untuk rest. ini adalah dibangun untuk exactly case docs describe: sebuah route like/blog/[slug]“where you want to prerender your most recent/popular content but server-render the long tail.” (terjemahan) “where Anda ingin prerender Anda sebagian besar recent/popular konten tetapi server-render panjang tail.”
Because prerendered routes shrink server bundle, sebuah mostly-prerendered situs
dengan sebuah few 'auto'/false routes deploys sebuah smaller, cheaper, faster function —
sebuah efficiency win independent dari SEO.
Dynamic routes perlu sebuah entries function
prerender crawler discovers halaman oleh following <a> tautan dari Anda entry
poin. itu berfungsi untuk static routes, tetapi sebuah dynamic route like /blog/[slug] memiliki
no fixed URL untuk crawler untuk temukan. jika nothing tautan untuk sebuah given slug, SvelteKit
won’t know ini exists — dan Anda’ll hit classic bangun error itu routes “were
marked as prerenderable, but were not prerendered.” (terjemahan) “adalah
marked sebagai prerenderable, tetapi adalah not prerendered.”
fix adalah sebuah explicit 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. Without ini, prerendering hanya covers slugs tautan crawler happens untuk temukan.
/blog/[slug] pattern di wild
Put two together dan Anda memiliki canonical mixed-situs setup: prerender = 'auto' plus sebuah entries function itu mengembalikan Anda recent dan popular posts.
itu get static HTML di bangun time; anything not di list falls melalui untuk SSR
pada demand. baru posts render dynamically until next bangun prerenders them. ini adalah
pragmatic middle ground antara “prerender all 40,000 posts every 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 affect SEO
config.runtime = 'edge' adalah per-route (pada Vercel)
Edge isn’t sebuah semua-atau-nothing 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 while keeping Node-dependent routes pada standard serverless (Node) runtime di yang sama deployment. Mix deliberately.
No fs, no arbitrary Node APIs
edge runtimes — Cloudflare Workers, Vercel Edge Functions, Netlify’s Deno Edge
Functions — don’t menyediakan Node’s fs. Cloudflare’s docs: “You can’t use fs in
Cloudflare Workers.” (terjemahan) “Anda dapat’t gunakan fs di
Cloudflare Workers.” Vercel’s: “You can’t use fs in edge functions.” (terjemahan) “Anda dapat’t gunakan fs di edge functions.” Both poin
untuk yang sama two escape hatches: gunakan read helper dari $app/server untuk access
bundled assets, atau “prerender the routes in question” (terjemahan) “prerender routes di pertanyaan” so file access happens
di bangun time alih-alih di permintaan time.
SEO-adjacent cases where ini bites: dynamic OG-image generation itu reads sebuah
font atau template file, file-based redirect maps, atau sebuah sitemap endpoint itu reads
konten off disk. apa pun dari itu either moves untuk $app/server’s read() atau moves untuk
prerender/bangun time. ini adalah not sebuah blocker — ini adalah sebuah “know before you pick edge” (terjemahan) “know sebelum Anda pick edge”
constraint.
Cold starts dan TTFB — when edge helps dan when ini doesn’t
Edge functions masih cold-start. sebuah cold edge function pada -nya pertama permintaan dapat menjadi slower daripada sebuah warm Node server, dan dramatically slower daripada sebuah prerendered file disajikan dari cache. Edge wins when function stays warm atau when ini adalah paired dengan aggressive caching so sebagian besar permintaan tidak pernah hit function di semua. ini adalah not automatically fastest option — “deploy to the edge” (terjemahan) “deploy untuk edge” adalah not sebuah synonym untuk “faster.” (terjemahan) “faster.” untuk sebuah konten situs, prerendered static output beats edge SSR pada TTFB setiap time, because there’s no function untuk start.
Generating sitemap.xml dan robots.txt (SvelteKit won’t)
ini adalah gap sebagian besar SvelteKit tutorials skip dan sebagian besar audits catch. SvelteKit generates no sitemap.xml dan no robots.txt automatically — regardless dari adapter, regardless dari how banyak halaman Anda prerender. sebuah fully static situs dengan thousands dari prerendered halaman masih ships dengan no sitemap unless Anda bangun one.
+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 depends pada Anda adapter
Here’s bagian itu ties ini whole artikel together: Anda sitemap strategy adalah downstream dari Anda adapter choice.
- pada
adapter-static, sitemap endpoint perluexport const prerender = trueso ini adalah disertakan di static output — there’s no server di runtime untuk generate ini pada permintaan. ini adalah baked di bangun time, which berarti ini adalah hanya sebagai fresh sebagai Anda last bangun. - pada sebuah Node/serverless/edge adapter, yang sama endpoint dapat generate sitemap
dynamically per permintaan dari Anda CMS atau database — selalu saat ini, no rebuild
needed. (pada sebuah edge adapter, remember
fsconstraint: pull URLs dari sebuah API atau binding, not sebuah disk read.)
So “should my sitemap be static or dynamic?” (terjemahan) “seharusnya my sitemap menjadi static atau dynamic?” pertanyaan isn’t sebuah separate decision — ini falls out dari adapter Anda sudah chose.
robots.txt: static file vs. endpoint
Two options. Drop sebuah plain robots.txt di Anda static/ folder (disajikan di
/robots.txt automatically), which adalah simplest choice dan fine untuk sebagian besar situs.
atau generate ini dari sebuah src/routes/robots.txt/+server.js endpoint when Anda perlu ini
untuk differ oleh environment (blocking crawler pada staging, allowing them di
production, misalnya). Either cara, don’t block Anda /_app/ bundle atau CSS —
itu breaks rendering untuk mesin itu melakukan render.
jika Anda’re coming di ini dari broader framework atau JavaScript-SEO angle, “where and when does rendering happen” (terjemahan) “where dan when melakukan rendering happen” logic here 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.
AI summary
sebuah condensed take pada Advanced versi:
- ** adapter perubahan where dan when, not what.** Adapters “take the built app as input and generate output for deployment” (terjemahan) “take dibangun app sebagai input dan generate output untuk deployment” — sama konten, berbeda timing (bangun vs. permintaan time) dan location (origin vs. edge).
- Why ini adalah sebuah SEO decision: TTFB → LCP → crawl capacity. Google: jika sebuah situs “responds quickly… the limit goes up… If the site slows down… Google crawls less.” (terjemahan) “responds quickly… limit goes up… jika situs slows down… Google melakukan crawl less.” No Google guidance names SvelteKit specifically — ini adalah umum guidance applied untuk SvelteKit mechanics.
- Adapters:
adapter-auto(zero-config, no options);adapter-static(SSG, konten situs, lowest TTFB);adapter-node(server Anda control, full Node APIs);adapter-vercel(serverless + edge + ISR);adapter-cloudflare(global edge Workers, nofs;adapter-cloudflare-workersadalah deprecated);adapter-netlify(functions atau Deno Edge Functions). - Prerender:
truemembangun static HTML dan menghapus route dari dynamic manifest;falseselalu SSRs;'auto'prerenders dan mempertahankan ini dynamic — mixed-situs alat untuk/blog/[slug](prerender popular, SSR panjang tail). - Dynamic routes perlu sebuah
entriesfunction atau Anda hit “marked as prerenderable, but were not prerendered” (terjemahan) “marked sebagai prerenderable, tetapi adalah not prerendered” error. - Edge constraints:
runtime: 'edge'adalah per-route (Vercel); nofs(“You can’t use fs in Cloudflare Workers” (terjemahan) “Anda dapat’t gunakan fs di Cloudflare Workers” / edge functions) — gunakan$app/server’sread()atau prerender; cold starts dapat membuat edge slower daripada sebuah warm server atau static file. - No dibangun-di sitemap/robots.txt. bangun
sitemap.xml/+server.jsendpoint (prerender = truepadaadapter-static; dynamic pada server/edge adapters). robots.txt viastatic/atau sebuah endpoint. - ISR ≠ prerender-plus: “Using ISR on a route with
export const prerender = truewill have no effect.” (terjemahan) “menggunakan ISR pada sebuah route dengan undefined akan memiliki no effect.” mereka’re alternatives.
Official documentation
Primary-source documentation dari SvelteKit dan mesin pencari.
SvelteKit
- Adapters • SvelteKit Docs — overview: adapters take dibangun app dan generate deployment output.
- Zero-config deployments (adapter-auto) • SvelteKit Docs — per-platform detection dan “does not take any options” (terjemahan) “melakukan not take apa pun options” limitation.
- Node server (adapter-node) • SvelteKit Docs — standalone Node server, environment variables, graceful shutdown.
- Static situs generation (adapter-static) • SvelteKit Docs — full-situs SSG, SSR requirement, dan SPA-fallback SEO warning.
- Vercel (adapter-vercel) • SvelteKit Docs — per-route
runtime,regions,split, dan Incremental Static Regeneration. - Cloudflare (adapter-cloudflare) • SvelteKit Docs — Workers/halaman,
platform.envbindings,nodejs_compat, danfslimitation. - Cloudflare Workers (adapter-cloudflare-workers, deprecated) • SvelteKit Docs — deprecated legacy adapter dan migration path.
- Netlify (adapter-netlify) • SvelteKit Docs — Node Functions vs. Deno-based Edge Functions (
edge: true), dan Forms prerender requirement. - halaman options (prerender, ssr, csr, config) • SvelteKit Docs —
prerender = true/false/'auto',entriesfunction, dan per-routeconfigincludingruntime: 'edge'.
- memahami JavaScript SEO Basics — render queue dan “not all bots can run JavaScript.” (terjemahan) “not semua bot dapat run JavaScript.”
- mengoptimalkan Anda anggaran crawling — crawl capacity tied untuk respons speed; “make your pages efficient to load.” (terjemahan) “membuat Anda halaman efficient untuk muat.”
Bing / Microsoft
- bingbot Series: JavaScript, Dynamic rendering, dan Cloaking. Oh My! — Bing’s prerendering/dynamic-rendering recommendation dan cloaking clarification.
- Fast Front-End performa untuk Microsoft Bing — Bing’s own SSR + CDN/edge-node architecture sebagai sebuah dunia nyata proof poin.
Quotes dari source
pada—record statements dari SvelteKit docs, Google, dan Bing. setiap tautan adalah sebuah deep tautan itu jumps untuk quoted passage pada source halaman.
SvelteKit docs — adapters & halaman options
- “adapter-auto does not take any options.” (terjemahan) “adapter-auto melakukan not take apa pun options.” — pada zero-config default adapter. Jump untuk quote
- pada
prerender = true— prerendered routes adalah “excluded from manifests used for dynamic SSR, making your server (or serverless/edge functions) smaller.” (terjemahan) “excluded dari manifests digunakan untuk dynamic SSR, membuat Anda server (atau serverless/edge functions) smaller.” Jump untuk quote - pada
'auto'—/blog/[slug]case where Anda ingin “prerender your most recent/popular content but server-render the long tail.” (terjemahan) “prerender Anda sebagian besar recent/popular konten tetapi server-render panjang tail.” Jump untuk quote - pada edge
fslimitation — “You can’t use fs in Cloudflare Workers.” (terjemahan) “Anda dapat’t gunakan fs di Cloudflare Workers.” Jump untuk quote - pada Vercel ISR vs. prerender — “Using ISR on a route with export const prerender = true will have no effect, since the route is prerendered at build time.” (terjemahan) “menggunakan ISR pada sebuah route dengan export const prerender = benar akan memiliki no effect, since route adalah prerendered di bangun time.” Jump untuk quote
Google — rendering & anggaran crawling
- “Keep in mind 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.” (terjemahan) “ingatlah itu 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.” Jump untuk quote
- “If the site responds quickly for a while, the limit goes up, meaning more connections can be used to crawl. If the site slows down or responds with server errors, the limit goes down and Google crawls less.” (terjemahan) “jika situs responds quickly untuk sebuah while, limit goes up, meaning more connections dapat menjadi digunakan untuk crawl. jika situs slows down atau responds dengan server errors, limit goes down dan Google melakukan crawl less.” Jump untuk quote
- “Make your pages efficient to load. If Google can load and render your pages faster, we might be able to read more content from your site.” (terjemahan) “membuat Anda halaman efficient untuk muat. jika Google dapat muat dan render Anda halaman faster, kami mungkin menjadi able untuk baca selengkapnya konten dari Anda situs.” Jump untuk quote
Bing — prerendering & -nya own edge architecture
- “We encourage detecting our bingbot user agent, prerendering the content on the server side and outputting static HTML for such sites…” (terjemahan) “kami encourage detecting kami bingbot pengguna agent, prerendering konten pada server side dan outputting static HTML untuk such situs…” — Fabrice Canel & Frédéric Dubut, Microsoft Bing. Jump untuk quote
- “User traffic routes first to the closest CDN node (called an ‘edge node’).” (terjemahan) “pengguna traffic routes pertama untuk closest CDN node (called sebuah ‘edge node’).” — Bing Search Quality Insights, pada Bing’s own SSR + edge architecture. Jump untuk quote
SvelteKit deployment SEO checklist
sebuah pass untuk confirm Anda adapter, prerender, dan sitemap setup won’t hurt crawler:
- Anda’ve moved off
adapter-autountuk sebuah explicit adapter jika Anda perlu apa pun configuration (edge, ISR, bindings). - adapter matches situs jenis —
adapter-staticuntuk pure konten, sebuah server/edge adapter untuk anything dengan per-permintaan logic. - konten routes adalah
prerender = true(atau'auto'); hanya genuinely dynamic routes adalah left untuk SSR. - Mixed dynamic routes (
/blog/[slug]) gunakanprerender = 'auto'dengan sebuahentriesfunction enumerating known paths. - No unresolved “marked as prerenderable, but were not prerendered” (terjemahan) “marked sebagai prerenderable, tetapi adalah not prerendered” bangun errors.
- jika apa pun route menggunakan
runtime: 'edge', ini melakukan not panggil Nodefs— file access menggunakan$app/server’sread()atau adalah prerendered. - Anda’ve accounted untuk cold starts pada edge/serverless — cacheable, static, atau warm where TTFB penting.
- sebuah sitemap.xml endpoint exists (
prerender = truepadaadapter-static; dynamic pada server/edge adapters). - sebuah robots.txt exists (di
static/atau sebagai sebuah+server.jsendpoint) dan melakukan not block/_app/atau CSS. - Anda adalah not trying untuk stack ISR pada sebuah
prerender = trueroute (ini memiliki no effect). - Anda verified rendered HTML dan respons speed di GSC pemeriksaan URL dan PageSpeed Insights.
mental models
1. Where dan when, not what. adapter tidak pernah perubahan Anda konten — ini perubahan when HTML adalah dibuat (bangun time vs. permintaan time) dan where (origin vs. edge). setiap deployment SEO pertanyaan reduces untuk itu two axes. tanyakan them sebelum Anda touch config.
2. Prerender menghapus sebuah route dari server.
prerender = true isn’t hanya “make it static” (terjemahan) “membuat ini static” — ini takes route out dari
dynamic manifest. itu shrinks Anda function dan aturan out sebuah dynamic fallback.
'auto' adalah exception: prerendered dan masih di manifest.
3. /blog/[slug] split.
default pattern untuk nyata konten situs: prerender entries Anda dapat name
(entries function mengembalikan recent/popular), SSR panjang tail. 'auto' adalah
switch itu membuat both benar di once.
4. Edge adalah sebuah trade, not sebuah upgrade.
Edge buys Anda geographic proximity (rendah TTFB when warm) dan costs Anda Node APIs
(no fs) dan cold-start risk. ini beats sebuah warm Node server hanya sometimes, dan
loses untuk prerendered static output pada TTFB selalu. Choose ini untuk sebuah alasan, not oleh
default.
5. sitemap mengikuti adapter.
“Static or dynamic sitemap?” (terjemahan) “Static atau dynamic sitemap?” isn’t sebuah separate decision. adapter-static →
prerendered sitemap, fresh hanya di bangun. server/edge adapter → per-permintaan
sitemap, selalu saat ini. adapter sudah answered pertanyaan.
6. Nothing generates two files. SvelteKit membuat no sitemap.xml dan no robots.txt, untuk apa pun adapter. jika Anda didn’t write them, mereka don’t exist. Bake ini ke Anda launch checklist.
Which adapter + prerender combo seharusnya I pick?
core “which path do I take?” (terjemahan) “which path melakukan I take?” pertanyaan di SvelteKit deployment adalah how seharusnya ini situs ship? Walk Anda situs melalui ini:
1. melakukan apa pun halaman perlu per-permintaan server logic — auth, personalization, live search, form handling, per-pengguna data? → No (setiap halaman adalah yang sama untuk setiap pengunjung): go untuk 2. → Yes: skip untuk 3.
2. Pure konten situs (blog, docs, marketing).
→ gunakan adapter-static, set prerender = true situs-wide (atau di root
layout). tambahkan sebuah prerendered sitemap.xml/+server.js (prerender = true) dan sebuah
static/robots.txt. Lowest TTFB, no cold starts, nothing untuk run. Stop here.
3. adalah whole situs dynamic, atau hanya beberapa routes? → hanya beberapa routes (mostly konten, sebuah few dynamic bits): go untuk 4. → Mostly/entirely dynamic (app, dashboard, ecommerce dengan per-pengguna data): go untuk 5.
4. konten situs dengan dynamic pockets.
→ gunakan server/edge adapter (adapter-node, -vercel, atau
-cloudflare). Mark konten routes prerender = true, dynamic routes
false. untuk /blog/[slug]-style routes dengan known-popular konten, gunakan
prerender = 'auto' + sebuah entries function. Generate sitemap dynamically
dari Anda CMS. Done.
5. App / dashboard / ecommerce (SSR-pertama). Now pick where SSR runs:
→ Predictable latency, Node libraries, Anda memiliki infra: adapter-node
(warm server, full Node APIs, no cold-start surprises).
→ Global audience, TTFB penting sebagian besar, no heavy Node deps: sebuah edge adapter
(adapter-cloudflare, atau adapter-vercel dengan runtime: 'edge' per route) —
accept no fs (gunakan $app/server’s read() atau prerender) dan cold starts.
Prerender hanya truly static shell (marketing, login).
Fourth path (Vercel hanya): jika sebuah route adalah “mostly static but occasionally
changes,” (terjemahan) “mostly static tetapi occasionally
perubahan,” pertimbangkan ISR (isr: { expiration }) alih-alih prerender = true
— tidak pernah both, since “ISR on a route with export const prerender = true will have
no effect.” (terjemahan) “ISR pada sebuah route dengan export const prerender = benar akan memiliki
no effect.”
seharusnya my sitemap menjadi static atau dynamic?
pada adapter-static? → Static/prerendered sitemap endpoint
(prerender = true). ini adalah baked di bangun; fine untuk situs itu rebuild pada publish.
pada sebuah Node/serverless/edge adapter? → Dynamic sitemap generated per permintaan
dari Anda CMS/DB — selalu saat ini, no rebuild. (pada edge, pull URLs dari sebuah API atau
binding, not sebuah disk fs read.)
tidak pernah: ship no sitemap because “the pages are all static.” (terjemahan) “ halaman adalah semua static.” Static output dan sitemap discoverability adalah unrelated — SvelteKit generates neither file untuk apa pun adapter.
SvelteKit deployment SEO — cheat sheet
Adapters di sebuah glance
| Adapter | Renders | Runtime | SEO note |
|---|---|---|---|
adapter-static | bangun time (SSG) | none | Lowest TTFB, no cold starts; konten situs |
adapter-node | permintaan time (SSR) | Node | Full Node APIs (fs ✅); Anda run server |
adapter-vercel | permintaan time | serverless / edge | Per-route runtime, regions, ISR |
adapter-cloudflare | permintaan time | V8 edge | Global edge; no fs; nodejs_compat |
adapter-netlify | permintaan time | Node / Deno edge | edge: true untuk Deno Edge Functions |
adapter-auto | (detects above) | — | Takes no options — scaffold hanya |
Prerender nilai
| nilai | Static HTML? | di dynamic manifest? | gunakan untuk |
|---|---|---|---|
true | ✅ | ❌ (dihapus) | Known static konten routes |
false | ❌ | ✅ | Genuinely dynamic routes |
'auto' | ✅ | ✅ | /blog/[slug] — prerender popular, SSR panjang tail |
Fast aturan
- Dynamic prerendered routes → tambahkan sebuah
entriesfunction (atau hit “not prerendered” (terjemahan) “not prerendered” error). runtime: 'edge'adalah per-route (Vercel) — mix edge dan Node routes.- Edge = no
fs→ gunakan$app/server’sread()atau prerender. - Cold starts membuat edge slower daripada sebuah warm server / static file pada pertama hit.
- ISR ≠ prerender —
isrpada sebuahprerender = trueroute melakukan nothing. - No auto sitemap/robots.txt — bangun both.
prerender = truepada sitemap endpoint untukadapter-static; dynamic pada server/edge. - tidak pernah block
/_app/atau CSS di robots.txt.
sebuah prerendered route adalah missing dari deployment
mungkin cause: crawler dapat not menemukan path, sebuah entries nilai adalah absent, atau prerendering failed. Fix: tambahkan dapat di-crawl tautan atau explicit entries dan treat bangun warnings sebagai release failures. Confirm: output manifest berisi route dan production mengembalikan complete HTML.
adapter-static fails pada sebuah dynamic route
mungkin cause: route cannot menjadi fully enumerated di bangun time. Fix: supply finite entries, redesign route, atau gunakan server-capable adapter untuk itu path. Confirm: selected adapter membangun dan setiap representative route mengembalikan intended respons.
Edge deployment throws filesystem atau Node API errors
mungkin cause: route code atau sebuah dependency assumes Node fitur unavailable di edge runtime. Fix: replace dependency, move berfungsi untuk sebuah compatible service, atau choose sebuah Node adapter. Confirm: production SSR succeeds without runtime exceptions.
Sitemap atau robots.txt mengembalikan HTML
mungkin cause: sebuah fallback route catches endpoint atau +server handler sets wrong body/headers. Fix: buat explicit endpoint handlers dengan correct konten jenis. Confirm: direct permintaan mengembalikan expected text/XML respons dan 200 status.
Metadata differs antara prerendered dan SSR routes
mungkin cause: head data adalah dimuat di berbeda code paths atau depends pada browser state. Fix: centralize metadata generation dari server/bangun-safe halaman data. Confirm: raw HTML untuk both route jenis berisi equivalent judul, canonical, dan robots logic.
Confirm what Anda adapter actually shipped
poin dari picking sebuah adapter dan prerendering adalah itu sebuah crawler gets fast, complete HTML. ini memeriksa confirm itu’s what actually happened — dari raw respons, not browser.
adalah halaman prerendered/SSR’d (konten di raw HTML)?
sebuah plain curl runs no JavaScript, so ini sees exactly what sebuah non-rendering crawler
sees.
macOS / Linux
# Raw HTML as the host sends it (no JS executed)
curl -sL "https://example.com/your-page/" -o raw.html
grep -o "Your unique headline text" raw.html # empty = CSR shell, not prerenderedWindows (PowerShell)
Invoke-WebRequest -Uri "https://example.com/your-page/" -OutFile raw.html
Select-String -Path raw.html -Pattern "Your unique headline text"adalah TTFB fast (atau adalah sebuah function cold-starting)?
TTFB feeds LCP dan crawl capacity, so mengukur ini. Hit URL cold, lalu warm:
# Time to first byte, twice — a big first number then a small one = cold start
for i in 1 2; do
curl -s -o /dev/null -w "TTFB: %{time_starttransfer}s\n" "https://example.com/your-page/"
donesebuah prerendered/static halaman seharusnya menjadi consistently rendah. sebuah besar pertama nilai itu drops pada kedua hit adalah sebuah classic serverless/edge cold start.
adalah ini route prerendered atau disajikan dynamically?
Static hosts dan CDNs biasanya reveal ini di headers (cache status, age,
x-vercel-cache, cf-cache-status):
curl -sI "https://example.com/your-page/" | grep -iE "cache|age|x-vercel|cf-"sebuah HIT (atau sebuah nonzero age) berarti Anda’re menjadi disajikan cached/prerendered konten;
sebuah MISS/DYNAMIC pada setiap permintaan berarti ini adalah rendering per permintaan.
melakukan sitemap actually exist dan kembalikan XML?
Since SvelteKit doesn’t generate one, verify yours adalah really there dengan right konten jenis:
curl -sI "https://example.com/sitemap.xml" | grep -iE "HTTP/|content-type"
# Want: 200 + content-type: application/xml (not text/html or a 404)DevTools console one-liner
Paste di browser console untuk compare rendered DOM terhadap what sebuah crawler perlu —
jika Anda headline adalah here tetapi missing dari curl output above, ini adalah
client-rendered:
// Is the content in the DOM, and does the sitemap resolve?
console.log('headline in DOM:', document.body.innerText.includes('Your unique headline text'));
fetch('/sitemap.xml').then(r => console.log('sitemap status:', r.status, r.headers.get('content-type')));periksa robots.txt isn’t blocking bundle
curl -sL "https://example.com/robots.txt" | grep -iE "disallow.*(/_app|\.js|\.css)"sebuah Disallow matching /_app/ (SvelteKit’s bundled output) atau Anda CSS berarti
mesin dapat’t render halaman — almost selalu sebuah mistake.
alat untuk debugging SvelteKit deployment SEO
- pemeriksaan URL (Google Search Console) — sumber kebenaran. Live-test sebuah URL dan periksa rendered HTML, screenshot, dan halaman resources untuk confirm konten dan metadata adalah present dan nothing adalah blocked.
- PageSpeed Insights — SvelteKit docs’ own recommended alat; surfaces TTFB dan Core Web Vitals (LCP/INP/CLS) itu Anda adapter choice sebagian besar affects.
- WebPageTest — waterfall + filmstrip untuk diagnosing TTFB dan cold-start timing pada edge/serverless deploys.
curl -w "%{time_starttransfer}"— quickest raw TTFB dan cold-start periksa (see Scripts tab).- Host dashboards (Vercel / Cloudflare / Netlify Analytics) — function invocation counts, cold-start rates, dan cache-hit ratios per route — ground truth untuk whether edge/serverless adalah actually fast untuk Anda.
- Screaming Frog SEO Spider — crawl dengan JS rendering pada/off untuk diff raw vs. rendered HTML di seluruh situs dan confirm prerendered routes adalah complete.
- Ahrefs situs Audit — surfaces missing/blocked sitemaps, rantai pengalihan, broken canonicals, dan indexability issues di scale.
Test yourself: SvelteKit Deployment SEO
Five quick pertanyaan pada adapters, prerendering, dan edge rendering di SvelteKit. Pick sebuah jawaban untuk setiap, lalu periksa.
Resources worth Anda time
My related writing
- JavaScript SEO: sebuah Definitive Guide — my full reference pada rendering modes (SSR, static rendering, prerendering, dan CSR pitfalls) itu underpin setiap adapter decision here. sebagai I put ini there, apa pun jenis dari SSR, static rendering, atau prerendering setup adalah going untuk menjadi fine untuk mesin pencari — which adalah exactly safety net behind ini adapter choices.
- Beginner’s Guide untuk SEO teknis — where rendering, crawling, dan Core Web Vitals fit di bigger picture.
My speaking
- How Search berfungsi (SlideShare) — my walkthrough dari crawling, rendering, pengindeksan, dan peringkat, which adalah backdrop untuk why TTFB dan rendering timing penting. (My standing disclaimer applies: “This is my understanding of systems… not going to be 100% complete or accurate.” (terjemahan) “ini adalah my understanding dari sistem… not going untuk menjadi 100% complete atau accurate.”)
dari sekitar industry
- Adapters • SvelteKit Docs — authoritative overview dari setiap official adapter dan how mereka’re specified di
svelte.config.js. - halaman options (prerender, ssr, csr, config) • SvelteKit Docs — per-route
prerendernilai,entriesfunction, dan per-routeconfigincludingruntime: 'edge', di team’s own kata. - Vercel (adapter-vercel) • SvelteKit Docs — edge runtime, regions, dan ISR-vs-prerender caveat.
- Cloudflare (adapter-cloudflare) • SvelteKit Docs — Workers/halaman deployment, bindings, dan
fslimitation. - SvelteKit • Cloudflare halaman docs — deployment mechanics dan
platformbindings dari Cloudflare’s side. - SvelteKit SEO: Anda Secret Weapon (Okupter) — sebuah practitioner guide untuk prerendering, meta tags, dan
+server.jssitemap/RSS pattern. - sebuah Deep Dive ke SvelteKit’s rendering Techniques (ini Dot Labs) — SSR/SSG/CSR mechanics dan per-route/per-layout config, dengan “SSR can be expensive” (terjemahan) “SSR dapat menjadi expensive” server-muat tradeoff.
- memahami JavaScript SEO Basics (Google Search Central) — render queue dan “not all bots can run JavaScript,” (terjemahan) “not semua bot dapat run JavaScript,” umum guidance setiap adapter choice sits di bawah.