SEO per la distribuzione di SvelteKit: Adapter, Prerendering e Rendering Edge
Le impostazioni dell'adapter di SvelteKit e del prerender per rotta decidono dove e quando vengono renderizzate le tue pagine — e questo determina TTFB, LCP e budget di crawl. Un approfondimento incentrato sulla distribuzione: scelta di adapter-static/node/vercel/cloudflare/netlify, prerender = true/false/'auto', vincoli del runtime edge e creazione di sitemap.xml e robots.txt.
Lingue
L'adapter di SvelteKit e l'impostazione del prerender per rotta decidono dove e quando una pagina viene renderizzata — HTML statico al momento della build, SSR su un server o SSR al edge — e questa decisione determina il TTFB, che influisce su LCP e capacità di crawl. Scegli adapter-static per siti puramente di contenuti, un adapter node/vercel/cloudflare con prerender per rotta per siti misti contenuti-plus-app, e un adapter edge quando il TTFB globale è importante (accettando cold start e nessun fs Node). prerender = 'auto' è lo strumento per siti misti. I runtime edge non possono leggere il filesystem. E SvelteKit non genera sitemap.xml o robots.txt — li costruisci come endpoint +server.js, con la strategia che dipende dal tuo adapter.
TL;DR — SvelteKit già renderizza le tue pagine sul server — quella parte è gestita. Questa pagina riguarda la prossima decisione: come il tuo sito viene creato e distribuito. Un adapter impacchetta la tua app SvelteKit per un host (un host di file statici, un server Node, o un servizio come Vercel o Cloudflare), e un’impostazione prerender per pagina decide se una pagina viene trasformata in un file HTML semplice in anticipo o renderizzata di nuovo a ogni visita. Queste due scelte decidono quanto velocemente i crawler ottengono il tuo HTML — e SvelteKit non creerà la tua sitemap o robots.txt, quindi devi aggiungerli tu stesso.
Cos’è un adapter (in termini semplici)
Se hai già creato un sito SvelteKit, sai che invia HTML reale al browser — il contenuto è lì prima che qualsiasi JavaScript venga eseguito. Bene. Questo è il problema SEO più difficile già risolto (e se non è ancora risolto per te, l’articolo sui fondamenti di SvelteKit in questa stessa sezione copre le modalità di rendering e la trappola del “guscio vuoto” che vuoi evitare prima).
Un adapter è il piccolo plugin che prende la tua build SvelteKit finita e la trasforma in qualcosa che un host specifico può eseguire. Evidence for this claim SvelteKit adapters transform a built application for deployment to a particular environment. Scope: SvelteKit adapters. Confidence: high · Verified: SvelteKit: Adapters Stesso sito, pacchetto diverso:
adapter-statictrasforma ogni pagina in un file HTML semplice, creato una volta. Ottimo per un blog, documentazione o un sito di marketing che non cambia per visitatore.adapter-nodeavvolge la tua app in un server Node.js che gestisci tu stesso.adapter-vercel,adapter-netlify,adapter-cloudflarelo impacchettano per quei servizi di hosting, che renderizzano le pagine su richiesta — a volte su server “ai margini,” fisicamente vicini ai tuoi visitatori.
Il contenuto è identico in tutti i casi. Ciò che cambia è quando viene creato l’HTML (in anticipo, o a ogni richiesta) e dove (un server, o una rete globale).
Perché questa è una decisione SEO, non solo tecnica
La cosa principale: velocità. Una pagina che è già un file statico si carica quasi istantaneamente. Una pagina che deve essere creata sul server richiede un momento. E Google ha detto chiaramente che se il tuo sito “risponde rapidamente per un po’, il limite aumenta, il che significa che più connessioni possono essere usate per la scansione. Se il sito rallenta… il limite diminuisce e Google scansiona meno.” Quindi una distribuzione lenta non infastidisce solo gli utenti — può significare che Google legge meno del tuo sito.
La versione semplice della decisione
- Un sito di contenuti (blog, documentazione, marketing) → usa
adapter-statice prerenderizza tutto. Il più veloce possibile, niente da rompere. - Un sito di contenuti con alcuni elementi dinamici (ricerca, commenti) → usa un adapter
server (
node/vercel/cloudflare) e segna le tue pagine di contenutoprerender = true, lasciando gli elementi dinamici da renderizzare su richiesta. - Un’app o una dashboard con pagine personalizzate per utenti con accesso → renderizza sul server (SSR), prerenderizza solo le pagine di marketing pubbliche.
Non dimenticare i due file che SvelteKit non creerà per te
SvelteKit non genera automaticamente una sitemap.xml o un robots.txt. Li aggiungi
tu stesso — di solito come un piccolo file endpoint (sitemap.xml/+server.js)
e sia un file nella tua cartella static/ o un altro endpoint per
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 È facile dimenticarlo perché la maggior parte dei framework che renderizzano HTML per
te sembrano “completi.” Questi due non lo sono.
Vuoi la versione più approfondita — cosa fa ogni adapter al rendering, come
prerender = 'auto' gestisce un sito misto, perché le edge function non possono leggere file,
e come la strategia della sitemap cambia con il tuo adapter? Passa alla scheda
Avanzate.
TL;DR — L’adapter non cambia cosa SvelteKit renderizza — cambia dove e quando: statico al build-time (
adapter-static), al request-time su un server che gestisci tu (adapter-node), o al request-time su funzioni serverless/edge (adapter-vercel/-netlify/-cloudflare).prerender = trueper rotta genera HTML statico e rimuove la rotta dal manifest dinamico;prerender = 'auto'pre-renderizza e la mantiene nel manifest — lo strumento per siti misti/blog/[slug]. I runtime edge girano su isolate V8: nientefsdi Node, e i cold start penalizzano il TTFB, che alimenta l’LCP e (secondo il documento sul crawl budget di Google) la capacità di crawl. SvelteKit non genera nessun sitemap.xml o robots.txt — creali come endpoint+server.js, e nota che la strategia dipende dall’adapter. Questo è un companion più mirato e incentrato sul deployment rispetto all’articolo sui fondamenti SEO di SvelteKit in questa sezione; do per scontato che tu sappia già che SvelteKit è SSR-by-default e non tornerò su questo punto qui.
L’idea chiave che fa scattare tutto
L’adapter non cambia cosa viene renderizzato. Cambia dove e quando.
Questo è tutto. I documenti di SvelteKit lo dicono con precisione: gli adapter “take the
built app as input and generate output for 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 I tuoi componenti, le tue
funzioni load, i tuoi metadati <svelte:head> — identici su ogni adapter.
Ciò che cambia è:
- Quando viene prodotto l’HTML: al build time (statico/pre-renderizzato) o al request time (SSR su un server, funzione serverless o funzione edge).
- Dove viene prodotto: su un singolo server di origine, su una funzione serverless regionale, o su una rete edge vicina al visitatore.
Tutto ciò che segue è una conseguenza di questi due assi.
Perché le scelte di deployment sono scelte SEO
La catena è breve e ben documentata: TTFB → LCP → capacità di crawl.
Il time to first byte è quanto tempo impiega l’host per iniziare a inviare la risposta. Un file pre-renderizzato servito da una cache CDN ha un TTFB quasi pari a zero. Un server che deve renderizzare la pagina ne ha uno più alto. Una funzione serverless o edge con cold start può averne uno molto più alto al primo accesso. Il TTFB è un input diretto per il Largest Contentful Paint — non puoi dipingere ciò che non hai ricevuto — e l’LCP è un segnale Core Web Vitals.
Il lato crawl è dove Google è più esplicito. Dalla documentazione sul crawl budget: “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.” (traduzione) «Se il sito risponde rapidamente per un po’, il limite sale, il che significa che è possibile usare più connessioni per il crawl. Se il sito rallenta o risponde con errori del server, il limite scende e Google esegue meno crawl.» E la riga sulle best practice: “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.” (traduzione) «Rendi le tue pagine efficienti da caricare. Se Google può caricare e renderizzare le tue pagine più velocemente, potremmo essere in grado di leggere più contenuti dal tuo sito.» Una funzione edge con cold start che è lenta a rispondere è soggetta alla stessa dinamica di un server di origine lento.
Una nota di onestà fin dall’inizio: Google non pubblica alcuna guida specifica per SvelteKit.
Non esiste un documento o un episodio di Search Off the Record che nomini gli adapter di SvelteKit,
prerender = 'auto' o i cold start edge. Quello che sto facendo qui è applicare
le linee guida generali di Google su rendering e crawl budget ai meccanismi specifici di SvelteKit
— non citare un rappresentante che ha commentato SvelteKit, perché nessuno l’ha fatto. Il
quadro di Google secondo cui “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” (traduzione) «il server-side o il pre-rendering è comunque un’ottima idea perché
rende il tuo sito più veloce per utenti e crawler, e non tutti i bot possono eseguire
JavaScript» è l’ancora ufficiale più vicina, ed è indipendente dal framework.
Scegliere un adapter per risultati SEO
adapter-auto — il default zero-config, e il suo limite
I nuovi progetti SvelteKit includono adapter-auto. Rileva la piattaforma —
Vercel, Netlify, Cloudflare Pages, Azure, AWS — e installa l’adapter corrispondente
al momento della build. È un buon punto di partenza, ma c’è un limite netto che
vale la pena conoscere: adapter-auto non accetta opzioni. Nel momento in cui
hai bisogno di { edge: true }, binding Cloudflare, ISR di Vercel o qualsiasi
configurazione specifica della piattaforma, installi direttamente l’adapter
sottostante (adapter-vercel, adapter-cloudflare, ecc.). Tratta auto come uno
scaffold, non come una decisione di produzione.
adapter-static — SSG completo, per siti content-first
adapter-static prerenderizza l’intero sito in file statici al momento della
build. Nessun server viene eseguito; un host serve HTML piatto. 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 Per un sito content-first questo è il
profilo SEO più forte che puoi avere — TTFB più basso, nessun cold start, nulla
che possa fallire. L’unico requisito è la trappola trattata ampiamente
nell’articolo sui fondamenti: SSR deve rimanere attivo durante la build, altrimenti
ottieni shell vuote invece di HTML renderizzato. Non lo rispiego qui oltre a
segnalarlo.
Il problema è la rigidità. Qualsiasi cosa che richieda davvero logica server per richiesta (ricerca vera, contenuti per utente, gestione di form senza un endpoint di terze parti) non può vivere su una build puramente statica — che è esattamente a cosa servono i prossimi adapter.
adapter-node — un server che controlli tu
adapter-node produce un server Node.js autonomo. Lo esegui tu, lo ridimensioni
tu, possiedi tu il TTFB. Questa è l’opzione più flessibile e quella con meno
sorprese a runtime — API Node complete, incluso fs. È una buona scelta quando
hai già infrastruttura, hai bisogno di librerie Node che i runtime edge non possono
eseguire, o vuoi tempi di risposta prevedibili (senza cold start) da un server
caldo. Il compromesso è operativo: stai eseguendo un server, e la sua velocità e
disponibilità ora sono la tua capacità di crawling.
adapter-vercel — serverless, edge e ISR
adapter-vercel esegue il deploy sulle funzioni serverless di Vercel per
default, con diverse leve rilevanti per la SEO impostate per rotta tramite
export const config:
runtime: 'edge'sposta quella rotta al runtime edge di Vercel (più sotto).regionscontrolla dove vengono eseguite le funzioni serverless — più vicine ai tuoi utenti (o al tuo database) significa latenza inferiore.israbilita la Rigenerazione Statica Incrementale:isr: { expiration: 60 }serve un asset statico in cache e lo rigenera dopo la finestra, dando “the performance and cost advantages of prerendered content with the flexibility of dynamically rendered content.” (traduzione) «i vantaggi in termini di prestazioni e costi dei contenuti prerenderizzati con la flessibilità dei contenuti renderizzati dinamicamente.» L’ISR è un vero e proprio quarto percorso tra puro statico e puro SSR — ma nota l’avvertenza della stessa documentazione: “Using ISR on a route withexport const prerender = truewill have no effect, since the route is prerendered at build time.” (traduzione) «Usare ISR su una rotta conexport const prerender = truenon avrà alcun effetto, poiché la rotta viene prerenderizzata al momento della build.» ISR e prerender sono alternative, non impilabili.
adapter-cloudflare — Workers/Pages, edge globale
adapter-cloudflare punta a Cloudflare Workers e Pages — SSR su una rete edge
globale, spesso il TTFB più basso per un pubblico geograficamente distribuito. Il
vincolo importante è il runtime: i Workers girano su isolate V8, non su Node.
Dalla documentazione: “You can’t use fs in Cloudflare Workers.” (traduzione)
«Non puoi usare fs in Cloudflare Workers.» Alcune API Node funzionano solo dietro
il flag di compatibilità nodejs_compat, e anche in quel caso il supporto non è
uno a uno. Se stavi leggendo file al momento della richiesta (una mappa di
redirect, un file di dati, input per immagini OG personalizzate), quel codice
richiede una ripensata — trattata nella sezione edge qui sotto.
(Il vecchio adapter-cloudflare-workers è deprecato; i nuovi progetti usano
adapter-cloudflare, che gestisce sia Workers che Pages. Se sei su quello
vecchio, migrare è il percorso consigliato.)
adapter-netlify — funzioni o Edge Functions (Deno)
adapter-netlify esegue il deploy sulle funzioni basate su Node di Netlify per impostazione predefinita, oppure su Edge Functions basate su Deno con edge: true. Stessa forma di Vercel: serverless predefinito con opt-in edge. Una nota specifica di SvelteKit: Netlify Forms richiede che la pagina del modulo sia prerenderizzata affinché Netlify possa rilevare il markup del modulo al momento del deploy, il che è un piccolo requisito “prerenderizza questa rotta” aggiunto alla scelta dell’adapter.
La decisione, in una riga ciascuna
- Sito di solo contenuto →
adapter-static, prerenderizza tutto. - Sito di contenuto con aree dinamiche →
adapter-node/-vercel/-cloudflare,prerender = truesul contenuto,false/'auto'sulle rotte dinamiche. - App/dashboard con personalizzazione → SSR-first (node o edge), prerenderizza solo la shell statica (marketing, login).
- Pubblico globale, sensibile al TTFB → un adapter edge per le rotte dinamiche, accettando i vincoli delle API Node e la realtà del cold-start.
(La scheda Decision Tree esplora questo come un flusso ramificato.)
Strategia di prerendering per siti misti
Cosa fanno realmente true / false / 'auto'
export const prerender è un’opzione di pagina per rotta (o per layout), e i tre
valori non sono solo on/off:
true— costruisci questa rotta in HTML statico al momento della build. In modo critico, è “esclusa dai manifest usati per SSR dinamico, rendendo il tuo server (o le funzioni serverless/edge) più piccolo.” Una volta prerenderizzata, la rotta non può ripiegare sul rendering dinamico — è statica, punto e basta.false— renderizza sempre su richiesta. Nessun file statico.'auto'— lo strumento per siti misti. Prerenderizza la rotta e la mantiene nel manifest del server dinamico, così la stessa rotta può essere servita staticamente per percorsi noti e renderizzata dal server per il resto. È costruito esattamente per il caso che i documenti descrivono: una rotta come/blog/[slug]“dove vuoi prerenderizzare i tuoi contenuti più recenti/popolari ma server-renderizzare la coda lunga.”
Poiché le rotte prerenderizzate riducono il bundle del server, un sito per lo più prerenderizzato
con poche rotte 'auto'/false distribuisce una funzione più piccola, più economica e più veloce —
un vantaggio di efficienza indipendente dalla SEO.
Le rotte dinamiche richiedono una funzione entries
Il crawler di prerendering scopre le pagine seguendo i link <a> dai tuoi punti di ingresso.
Funziona per le rotte statiche, ma una rotta dinamica come /blog/[slug] non ha
un URL fisso che il crawler possa trovare. Se nessun link punta a un dato slug, SvelteKit
non saprà che esiste — e incontrerai il classico errore di build secondo cui le rotte “erano
contrassegnate come prerenderizzabili, ma non sono state prerenderizzate.”
La soluzione è una funzione entries esplicita (o config.kit.prerender.entries) che
enumera i valori dei parametri:
// src/routes/blog/[slug]/+page.server.js
export const prerender = true;
export function entries() {
return [
{ slug: 'hello-world' },
{ slug: 'sveltekit-deployment-seo' },
];
}In pratica generi quella lista dal tuo CMS o dalla directory dei contenuti. Senza di essa, il prerendering copre solo gli slug che il crawler di link trova per caso.
Il pattern /blog/[slug] nel mondo reale
Metti insieme le due cose e hai la configurazione canonica per siti misti: prerender = 'auto' più una funzione entries che restituisce i tuoi post recenti e popolari.
Quelli ottengono HTML statico al momento della build; tutto ciò che non è nella lista ricade su SSR
su richiesta. I nuovi post vengono renderizzati dinamicamente fino alla build successiva che li prerenderizza. È
il compromesso pragmatico tra “prerenderizza tutti i 40.000 post a ogni build” e
“renderizza ogni post a ogni richiesta.”
Vincoli del runtime edge che influiscono sulla SEO
config.runtime = 'edge' è per rotta (su Vercel)
Edge non è un interruttore tutto-o-niente. Su Vercel è un’opzione di pagina per rotta:
// +page.server.js or +server.js
export const config = { runtime: 'edge' };Ciò significa che puoi spingere rotte ad alto traffico e memorizzabili nella cache verso l’edge per un TTFB basso mantenendo le rotte dipendenti da Node sul runtime serverless (Node) standard nello stesso deployment. Mescola deliberatamente.
Niente fs, niente API Node arbitrarie
I runtime edge — Cloudflare Workers, Vercel Edge Functions, Netlify’s Deno Edge
Functions — non forniscono fs di Node. La documentazione di Cloudflare: “You can’t use fs in
Cloudflare Workers.” Quella di Vercel: “You can’t use fs in edge functions.” Entrambe
indicano le stesse due vie di fuga: usa l’helper read di $app/server per accedere
agli asset inclusi nel bundle, oppure “prerender the routes in question” così che l’accesso ai file
avvenga in fase di build invece che al momento della richiesta.
I casi legati alla SEO in cui questo è un problema: generazione dinamica di immagini OG che legge un
file di font o un template, mappe di redirect basate su file, o un endpoint per la sitemap che legge
contenuti dal disco. Ognuno di questi o passa a read() di $app/server o viene spostato
in fase di prerender/build. Non è un blocco — è un vincolo “sapere prima di scegliere edge”.
Cold start e TTFB — quando edge aiuta e quando no
Le funzioni edge hanno comunque il cold start. Una funzione edge fredda alla prima richiesta può essere più lenta di un server Node caldo, e drammaticamente più lenta di un file prerenderizzato servito dalla cache. Edge vince quando la funzione rimane calda o quando è abbinata a una memorizzazione nella cache aggressiva così che la maggior parte delle richieste non raggiunga mai la funzione. Non è automaticamente l’opzione più veloce — “deploy sull’edge” non è sinonimo di “più veloce.” Per un sito di contenuti, l’output statico prerenderizzato batte la SSR edge sul TTFB ogni volta, perché non c’è nessuna funzione da avviare.
Generare sitemap.xml e robots.txt (SvelteKit non lo fa)
Questo è il vuoto che la maggior parte dei tutorial su SvelteKit salta e che la maggior parte degli audit rileva. SvelteKit genera nessun sitemap.xml e nessun robots.txt automaticamente — indipendentemente dall’adapter, indipendentemente da quante pagine prerenderizzi. Un sito completamente statico con migliaia di pagine prerenderizzate viene comunque pubblicato senza sitemap a meno che non ne crei una.
Il pattern dell’endpoint +server.js
La sitemap idiomatica è un endpoint di rotta che restituisce XML con il giusto
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' },
});
}La strategia dipende dal tuo adapter
Ecco la parte che lega insieme tutto questo articolo: la tua strategia per la sitemap è a valle della scelta dell’adapter.
- Su
adapter-static, l’endpoint della sitemap ha bisogno diexport const prerender = truecosì che sia incluso nell’output statico — non c’è un server a runtime per generarlo su richiesta. Viene creato in fase di build, il che significa che è fresco solo quanto la tua ultima build. - Su un adapter Node/serverless/edge, lo stesso endpoint può generare la sitemap
dinamicamente per richiesta dal tuo CMS o database — sempre aggiornata, nessuna rebuild
necessaria. (Su un adapter edge, ricorda il vincolo
fs: prendi gli URL da un’API o da un binding, non da una lettura dal disco.)
Quindi la domanda “la mia sitemap dovrebbe essere statica o dinamica?” non è una decisione separata — deriva dall’adapter che hai già scelto.
robots.txt: file statico vs. endpoint
Due opzioni. Metti un semplice robots.txt nella tua cartella static/ (servito su
/robots.txt automaticamente), che è la scelta più semplice e va bene per la maggior parte dei siti.
Oppure generarlo da un endpoint src/routes/robots.txt/+server.js quando hai bisogno che
cambi in base all’ambiente (bloccando i crawler in staging, permettendoli in
produzione, per esempio). In ogni caso, non bloccare il tuo bundle /_app/ o i CSS —
questo rompe il rendering per i motori che renderizzano.
Se arrivi da una prospettiva più ampia di framework o JavaScript-SEO, la logica “dove e quando avviene il rendering” qui è la stessa logica che governa la JavaScript SEO in generale, e il pezzo sui fondamenti di SvelteKit in questa sezione copre le modalità di rendering e i pattern di metadati su cui questo articolo si basa.
Riepilogo AI
Una sintesi della versione Advanced:
- L’adattatore cambia dove e quando, non cosa. Gli adattatori “prendono l’app compilata come input e generano output per la distribuzione” — stesso contenuto, tempi diversi (build vs. tempo di richiesta) e posizione (origine vs. edge).
- Perché è una decisione SEO: TTFB → LCP → capacità di crawl. Google: se un sito “risponde rapidamente… il limite aumenta… Se il sito rallenta… Google esegue meno crawl.” Nessuna guida Google menziona SvelteKit specificamente — questa è una guida generale applicata alla meccanica di SvelteKit.
- Adattatori:
adapter-auto(configurazione zero, nessuna opzione);adapter-static(SSG, siti di contenuti, TTFB più basso);adapter-node(server che controlli, API Node complete);adapter-vercel(serverless + edge + ISR);adapter-cloudflare(Workers edge globali, nientefs;adapter-cloudflare-workersè deprecato);adapter-netlify(funzioni o Deno Edge Functions). - Prerender:
truegenera HTML statico e rimuove la rotta dal manifest dinamico;falseesegue sempre SSR;'auto'prerenderizza e la mantiene dinamica — lo strumento per siti misti per/blog/[slug](prerenderizza i popolari, SSR per la coda lunga). - Le rotte dinamiche richiedono una funzione
entrieso ottieni l’errore “marked as prerenderable, but were not prerendered”. - Vincoli edge:
runtime: 'edge'è per-rotta (Vercel); nientefs(“You can’t use fs in Cloudflare Workers” / funzioni edge) — usaread()di$app/servero prerenderizza; i cold start possono rendere l’edge più lento di un server caldo o di un file statico. - Nessuna sitemap/robots.txt integrata. Crea un endpoint
sitemap.xml/+server.js(prerender = truesuadapter-static; dinamico su adattatori server/edge). robots.txt tramitestatic/o un endpoint. - ISR ≠ prerender-plus: “Using ISR on a route with
export const prerender = truewill have no effect.” Sono alternative.
Documentazione ufficiale
Documentazione di fonti primarie da SvelteKit e dai motori di ricerca.
SvelteKit
- Adapters • SvelteKit Docs — la panoramica: gli adattatori prendono l’app compilata e generano output di distribuzione.
- Zero-config deployments (adapter-auto) • SvelteKit Docs — rilevamento per piattaforma e il limite “does not take any options”.
- Node servers (adapter-node) • SvelteKit Docs — il server Node autonomo, variabili d’ambiente, spegnimento graduale.
- Static site generation (adapter-static) • SvelteKit Docs — SSG per l’intero sito, il requisito SSR e l’avviso SEO per il fallback SPA.
- Vercel (adapter-vercel) • SvelteKit Docs —
runtimeper-rotta,regions,splite Incremental Static Regeneration. - Cloudflare (adapter-cloudflare) • SvelteKit Docs — Workers/Pages, binding
platform.env,nodejs_compate la limitazionefs. - Cloudflare Workers (adapter-cloudflare-workers, deprecated) • SvelteKit Docs — l’adattatore legacy deprecato e il percorso di migrazione.
- Netlify (adapter-netlify) • SvelteKit Docs — Node Functions vs. Deno-based Edge Functions (
edge: true) e il requisito di prerender per i Forms. - Page options (prerender, ssr, csr, config) • SvelteKit Docs —
prerender = true/false/'auto', la funzioneentrieseconfigper-rotta inclusoruntime: 'edge'.
- Understand JavaScript SEO Basics — la coda di rendering e “not all bots can run JavaScript.”
- Optimize your crawl budget — capacità di crawl legata alla velocità di risposta; “make your pages efficient to load.”
Bing / Microsoft
- Serie bingbot: JavaScript, rendering dinamico e cloaking. Oh mamma! — La raccomandazione di Bing sul prerendering/rendering dinamico e il chiarimento sul cloaking.
- Prestazioni front-end veloci per Microsoft Bing — L’architettura SSR + CDN/edge node di Bing come esempio reale.
Citazioni dalla fonte
Dichiarazioni ufficiali dalla documentazione di SvelteKit, Google e Bing. Ogni link è un link profondo che salta al passaggio citato nella pagina di origine.
Documentazione SvelteKit — adapter e opzioni di pagina
- “adapter-auto does not take any options.” (traduzione) «adapter-auto non accetta alcuna opzione.» Vai alla citazione
- Su
prerender = true— le rotte prerenderizzate sono “excluded from manifests used for dynamic SSR, making your server (or serverless/edge functions) smaller.” (traduzione) «escluse dai manifest usati per la SSR dinamica, rendendo il tuo server (o le funzioni serverless/edge) più piccolo.» Vai alla citazione - Su
'auto'— il caso/blog/[slug]in cui vuoi “prerender your most recent/popular content but server-render the long tail.” (traduzione) «prerenderizzare i tuoi contenuti più recenti/popolari ma eseguire il server-render della coda lunga.» Vai alla citazione - Sul limite
fsedge — “You can’t use fs in Cloudflare Workers.” (traduzione) «Non puoi usare fs in Cloudflare Workers.» Vai alla citazione - Su 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.” (traduzione) «Usare ISR su una rotta con export const prerender = true non avrà alcun effetto, poiché la rotta viene prerenderizzata al momento della build.» Vai alla citazione
Google — rendering e crawl budget
- “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.” (traduzione) «Tieni presente che il server-side o il pre-rendering è ancora un’ottima idea perché rende il tuo sito più veloce per utenti e crawler, e non tutti i bot possono eseguire JavaScript.» Vai alla citazione
- “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.” (traduzione) «Se il sito risponde rapidamente per un po’, il limite aumenta, il che significa che più connessioni possono essere usate per il crawling. Se il sito rallenta o risponde con errori del server, il limite diminuisce e Google esegue meno crawl.» Vai alla citazione
- “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.” (traduzione) «Rendi le tue pagine efficienti da caricare. Se Google può caricare e rendere le tue pagine più velocemente, potremmo essere in grado di leggere più contenuti dal tuo sito.» Vai alla citazione
Bing — prerendering e la sua architettura edge
- “We encourage detecting our bingbot user agent, prerendering the content on the server side and outputting static HTML for such sites…” (traduzione) «Incoraggiamo il rilevamento del nostro user agent bingbot, il prerendering del contenuto lato server e l’output di HTML statico per tali siti…» — Fabrice Canel & Frédéric Dubut, Microsoft Bing. Vai alla citazione
- “User traffic routes first to the closest CDN node (called an ‘edge node’).” (traduzione) «Il traffico utente viene instradato prima al nodo CDN più vicino (chiamato ‘edge node’).» — Bing Search Quality Insights, sull’architettura SSR + edge di Bing. Vai alla citazione
Checklist SEO per il deployment di SvelteKit
Un passaggio per confermare che la configurazione di adapter, prerender e sitemap non danneggi i crawler:
- Hai abbandonato
adapter-autoper un adapter esplicito se hai bisogno di qualsiasi configurazione (edge, ISR, binding). - L’adapter corrisponde al tipo di sito —
adapter-staticper contenuti puri, un adapter server/edge per qualsiasi cosa con logica per richiesta. - Le rotte di contenuto sono
prerender = true(o'auto'); solo le rotte realmente dinamiche sono lasciate alla SSR. - Le rotte dinamiche miste (
/blog/[slug]) usanoprerender = 'auto'con una funzioneentriesche enumera i percorsi noti. - Nessun errore di build non risolto “marked as prerenderable, but were not prerendered”.
- Se una rotta usa
runtime: 'edge', non chiamafsdi Node — l’accesso ai file usaread()di$app/servero è prerenderizzato. - Hai considerato i cold start su edge/serverless — memorizzabili in cache, statici, o caldi dove TTFB conta.
- Esiste un endpoint sitemap.xml (
prerender = truesuadapter-static; dinamico su adapter server/edge). - Esiste un robots.txt (in
static/o come endpoint+server.js) e non blocca/_app/o CSS. - Non stai cercando di impilare ISR su una rotta
prerender = true(non ha effetto). - Hai verificato l’HTML renderizzato e la velocità di risposta in GSC URL Inspection e PageSpeed Insights.
I modelli mentali
1. Dove e quando, non cosa. L’adapter non cambia mai il tuo contenuto — cambia quando l’HTML viene creato (tempo di build vs. tempo di richiesta) e dove (origine vs. edge). Ogni domanda SEO sul deployment si riduce a questi due assi. Chiedile prima di toccare la configurazione.
2. Il prerender rimuove una rotta dal server.
prerender = true non è solo “rendilo statico” — toglie la rotta dal manifest dinamico.
Questo riduce la tua funzione ed esclude un fallback dinamico.
'auto' è l’eccezione: prerenderizzato e ancora nel manifest.
3. La divisione /blog/[slug].
Il pattern predefinito per i siti di contenuti reali: prerenderizza le voci che puoi nominare
(la funzione entries restituisce recenti/popolari), SSR per la coda lunga. 'auto' è
l’interruttore che rende entrambe le cose vere contemporaneamente.
4. Edge è un compromesso, non un aggiornamento.
Edge ti compra prossimità geografica (TTFB basso quando è caldo) e ti costa API Node
(niente fs) e rischio di cold start. Batte un server Node caldo solo a volte, e
perde contro l’output statico prerenderizzato su TTFB sempre. Sceglilo per una ragione, non per
default.
5. La sitemap segue l’adapter.
“Sitemap statica o dinamica?” non è una decisione separata. adapter-static →
sitemap prerenderizzata, fresca solo alla build. Adapter server/edge → sitemap
per richiesta, sempre aggiornata. L’adapter ha già risposto alla domanda.
6. Nulla genera i due file. SvelteKit non crea sitemap.xml né robots.txt, per nessun adapter. Se non li hai scritti, non esistono. Includilo nella tua checklist di lancio.
Quale combinazione adapter + prerender dovrei scegliere?
La domanda centrale “quale percorso prendo?” nel deployment di SvelteKit è come dovrebbe essere distribuito questo sito? Percorri il tuo sito attraverso questo:
1. Qualche pagina ha bisogno di logica server per richiesta — autenticazione, personalizzazione, ricerca live, gestione moduli, dati per utente? → No (ogni pagina è uguale per ogni visitatore): vai a 2. → Sì: salta a 3.
2. Sito di solo contenuti (blog, documentazione, marketing).
→ Usa adapter-static, imposta prerender = true a livello di sito (o nel
layout root). Aggiungi un endpoint prerenderizzato sitemap.xml/+server.js (prerender = true) e un
static/robots.txt. TTFB minimo, nessun cold start, nulla da eseguire. Fermati qui.
3. L’intero sito è dinamico, o solo alcune route? → Solo alcune route (per lo più contenuti, qualche parte dinamica): vai al punto 4. → Per lo più/totalmente dinamico (app, dashboard, ecommerce con dati per utente): vai al punto 5.
4. Sito di contenuti con parti dinamiche.
→ Usa un adapter server/edge (adapter-node, -vercel, o
-cloudflare). Segna le route di contenuti con prerender = true, le route dinamiche con
false. Per route tipo /blog/[slug] con contenuti noti e popolari, usa
prerender = 'auto' + una funzione entries. Genera la sitemap dinamicamente
dal tuo CMS. Fatto.
5. App / dashboard / ecommerce (SSR-first). Ora scegli dove esegue SSR:
→ Latenza prevedibile, librerie Node, hai l’infrastruttura: adapter-node
(server caldo, API Node complete, nessuna sorpresa di cold start).
→ Pubblico globale, TTFB è la priorità, nessuna dipendenza Node pesante: un adapter edge
(adapter-cloudflare, o adapter-vercel con runtime: 'edge' per route) —
accetta niente fs (usa read() di $app/server o prerender) e cold starts.
Prerenderizza solo la shell davvero statica (marketing, login).
Quarto percorso (solo Vercel): se una route è “per lo più statica ma cambia
occasionalmente,” considera ISR (isr: { expiration }) invece di prerender = true
— mai entrambi, poiché “ISR on a route with export const prerender = true will have
no effect.”
La mia sitemap dovrebbe essere statica o dinamica?
Su adapter-static? → Endpoint sitemap statico/prerenderizzato
(prerender = true). Viene generato in build; va bene per siti che si ricostruiscono alla pubblicazione.
Su un adapter Node/serverless/edge? → Sitemap dinamica generata per ogni richiesta
dal tuo CMS/DB — sempre aggiornata, nessuna ricostruzione. (Su edge, recupera gli URL da un’API o
binding, non da una lettura fs su disco.)
Mai: non pubblicare una sitemap perché “le pagine sono tutte statiche.” Output statico e scopribilità della sitemap non sono correlati — SvelteKit non genera nessuno dei due file per nessun adapter.
SEO per il deployment di SvelteKit — cheat sheet
Adapter a colpo d’occhio
| Adapter | Rendering | Runtime | Nota SEO |
|---|---|---|---|
adapter-static | Tempo di build (SSG) | nessuno | TTFB minimo, nessun cold start; siti di contenuti |
adapter-node | Tempo di richiesta (SSR) | Node | API Node complete (fs ✅); gestisci tu il server |
adapter-vercel | Tempo di richiesta | serverless / edge | runtime per route, regions, ISR |
adapter-cloudflare | Tempo di richiesta | V8 edge | Edge globale; niente fs; nodejs_compat |
adapter-netlify | Tempo di richiesta | Node / Deno edge | edge: true per Deno Edge Functions |
adapter-auto | (rileva quanto sopra) | — | Non accetta opzioni — solo per scaffold |
Valori di prerender
| Valore | HTML statico? | Nel manifest dinamico? | Usalo per |
|---|---|---|---|
true | ✅ | ❌ (rimosso) | Route di contenuti statici noti |
false | ❌ | ✅ | Route davvero dinamiche |
'auto' | ✅ | ✅ | /blog/[slug] — prerenderizza i popolari, SSR per la coda lunga |
Regole rapide
- Route dinamiche prerenderizzate → aggiungi una funzione
entries(o ricevi l’errore “not prerendered”). runtime: 'edge'è per route (Vercel) — puoi mescolare route edge e Node.- Edge = niente
fs→ usaread()di$app/servero prerender. - Cold starts rendono edge più lento di un server caldo / file statico al primo accesso.
- ISR ≠ prerender —
isrsu una route conprerender = truenon fa nulla. - Nessuna sitemap/robots.txt automatici — creali entrambi.
prerender = truesull’endpoint della sitemap peradapter-static; dinamico su server/edge. - Non bloccare mai
/_app/o CSS in robots.txt.
Una route prerenderizzata manca dal deployment
Causa probabile: il crawler non ha potuto scoprire il percorso, un valore entries è assente oppure il prerendering non è riuscito. Correzione: aggiungi link indicizzabili o voci esplicite e tratta gli avvisi di build come errori di rilascio. Conferma: il manifest di output contiene la rotta e la produzione restituisce HTML completo.
adapter-static fallisce su una rotta dinamica
Causa probabile: la rotta non può essere completamente enumerata al momento della build. Correzione: fornisci voci finite, riprogetta la rotta oppure usa un adapter con supporto server per quel percorso. Conferma: l’adapter selezionato compila e ogni rotta rappresentativa restituisce la risposta prevista.
Il deployment edge genera errori di filesystem o API Node
Causa probabile: il codice della rotta o una dipendenza presuppone funzionalità Node non disponibili nel runtime edge. Correzione: sostituisci la dipendenza, sposta il lavoro su un servizio compatibile oppure scegli un adapter Node. Conferma: la SSR in produzione riesce senza eccezioni di runtime.
Sitemap o robots.txt restituisce HTML
Causa probabile: una rotta di fallback intercetta l’endpoint oppure il gestore +server imposta body/header errati. Correzione: crea gestori di endpoint espliciti con i tipi di contenuto corretti. Conferma: le richieste dirette restituiscono la risposta testuale/XML prevista e lo stato 200.
I metadati differiscono tra rotte prerenderizzate e SSR
Causa probabile: i dati head vengono caricati in percorsi di codice diversi oppure dipendono dallo stato del browser. Correzione: centralizza la generazione dei metadati a partire dai dati di pagina sicuri per server/build. Conferma: l’HTML grezzo per entrambi i tipi di rotta contiene logica equivalente per title, canonical e robots.
Conferma cosa ha effettivamente distribuito il tuo adapter
Il punto di scegliere un adapter e fare prerendering è che un crawler riceva HTML veloce e completo. Questi controlli confermano che è ciò che è realmente accaduto — dalla risposta grezza, non dal browser.
La pagina è prerenderizzata/SSR (contenuto nell’HTML grezzo)?
Un semplice curl non esegue JavaScript, quindi vede esattamente ciò che vede un
crawler che non esegue il rendering.
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"Il TTFB è veloce (o una funzione sta facendo cold start)?
Il TTFB alimenta LCP e la capacità di crawling, quindi misuralo. Colpisci l’URL a freddo, poi a caldo:
# 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/"
doneUna pagina prerenderizzata/statica dovrebbe essere costantemente bassa. Un primo valore alto che scende al secondo colpo è un classico cold start serverless/edge.
Questa rotta è stata prerenderizzata o servita dinamicamente?
Gli host statici e le CDN di solito lo rivelano negli header (stato cache, age,
x-vercel-cache, cf-cache-status):
curl -sI "https://example.com/your-page/" | grep -iE "cache|age|x-vercel|cf-"Un HIT (o un age diverso da zero) significa che ti viene servito contenuto
in cache/prerenderizzato; un MISS/DYNAMIC a ogni richiesta significa che viene
eseguito il rendering per ogni richiesta.
La sitemap esiste davvero e restituisce XML?
Poiché SvelteKit non ne genera una, verifica che la tua sia realmente presente con il tipo di contenuto corretto:
curl -sI "https://example.com/sitemap.xml" | grep -iE "HTTP/|content-type"
# Want: 200 + content-type: application/xml (not text/html or a 404)One-liner per la console DevTools
Incolla nella console del browser per confrontare il DOM renderizzato con ciò di cui
un crawler ha bisogno — se il tuo titolo è qui ma manca dall’output curl sopra,
è renderizzato lato client:
// 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')));Controlla che robots.txt non blocchi il bundle
curl -sL "https://example.com/robots.txt" | grep -iE "disallow.*(/_app|\.js|\.css)"Un Disallow che corrisponde a /_app/ (l’output bundle di SvelteKit) o al tuo CSS
significa che i motori non possono renderizzare la pagina — quasi sempre un errore.
Strumenti per il debug della SEO di deployment SvelteKit
- URL Inspection (Google Search Console) — la fonte di verità. Testa dal vivo un URL e controlla l’HTML renderizzato, lo screenshot e le risorse della pagina per confermare che contenuti e metadati siano presenti e che nulla sia bloccato.
- PageSpeed Insights — lo strumento consigliato dalla stessa documentazione di SvelteKit; evidenzia TTFB e i Core Web Vitals (LCP/INP/CLS) che la tua scelta di adapter influenza maggiormente.
- WebPageTest — waterfall + filmstrip per diagnosticare TTFB e i tempi di avvio a freddo su deploy edge/serverless.
curl -w "%{time_starttransfer}"— il controllo grezzo più rapido di TTFB e avvio a freddo (vedi la scheda Scripts).- Dashboard dell’host (Vercel / Cloudflare / Netlify Analytics) — conteggi di invocazione delle funzioni, tassi di avvio a freddo e rapporti di cache-hit per rotta — la verità di fondo per capire se edge/serverless è davvero veloce per te.
- Screaming Frog SEO Spider — esegui una scansione con rendering JS attivo/disattivato per confrontare HTML grezzo vs. renderizzato su tutto il sito e confermare che le rotte prerenderizzate siano complete.
- Ahrefs Site Audit — evidenzia sitemap mancanti/bloccate, catene di redirect, canonical rotti e problemi di indicizzabilità su larga scala.
Mettiti alla prova: SEO per il deployment di SvelteKit
Cinque domande rapide su adapter, prerendering e rendering edge in SvelteKit. Scegli una risposta per ciascuna, poi controlla.
Risorse che meritano il tuo tempo
I miei articoli correlati
- JavaScript SEO: A Definitive Guide — il mio riferimento completo sui modi di rendering (SSR, rendering statico, prerendering e le insidie del CSR) che sono alla base di ogni decisione sugli adapter qui. Come ho scritto lì, qualsiasi configurazione SSR, rendering statico o prerendering andrà bene per i motori di ricerca — che è esattamente la rete di sicurezza dietro queste scelte di adapter.
- The Beginner’s Guide to Technical SEO — dove rendering, crawling e Core Web Vitals si inseriscono nel quadro più ampio.
I miei interventi
- How Search Works (SlideShare) — la mia spiegazione di crawling, rendering, indicizzazione e ranking, che fa da sfondo al motivo per cui TTFB e tempi di rendering contano. (Vale la mia consueta precisazione: “This is my understanding of systems… not going to be 100% complete or accurate.” (traduzione) «Questa è la mia comprensione dei sistemi… non sarà completa o accurata al 100%».)
Dal settore
- Adapters • SvelteKit Docs — la panoramica autorevole di ogni adapter ufficiale e di come vengono specificati in
svelte.config.js. - Page options (prerender, ssr, csr, config) • SvelteKit Docs — i valori
prerenderper rotta, la funzioneentriese laconfigper rotta inclusaruntime: 'edge', con le parole del team. - Vercel (adapter-vercel) • SvelteKit Docs — il runtime edge, le regioni e l’avvertenza su ISR vs prerender.
- Cloudflare (adapter-cloudflare) • SvelteKit Docs — deployment su Workers/Pages, binding e la limitazione di
fs. - SvelteKit • Cloudflare Pages docs — i meccanismi di deployment e i binding
platformdal lato Cloudflare. - SvelteKit SEO: Your Secret Weapon (Okupter) — una guida pratica a prerendering, meta tag e al pattern sitemap/RSS con
+server.js. - A Deep Dive into SvelteKit’s Rendering Techniques (This Dot Labs) — meccanismi SSR/SSG/CSR e configurazione per rotta/per layout, con il compromesso del server-load “SSR can be expensive”.
- Understand JavaScript SEO Basics (Google Search Central) — la coda di rendering e “not all bots can run JavaScript,” la guida generale sotto cui si colloca ogni scelta di adapter.