Questo pezzo è per chi ha un sito Astro su Cloudflare Pages e si chiede se spostarlo su Workers, e cosa si rompe nel farlo. Fa parte del filone Cloudflare di fnbit, accanto a Workers + D1 + R2 e al confronto Vercel vs Cloudflare vs VPS.
Non è il diario di una migrazione. Non ho cronometri né log da mostrarti. È una procedura costruita sulla documentazione ufficiale di Cloudflare e di Astro, verificata il 14 ottobre 2026, con le versioni lette quel giorno dal registry npm.
In breve: passare da Pages a Workers vuol dire rendere esplicito quello che Pages faceva da solo. Pagina 404, comportamento SPA, binding ASSETS, ordine tra Functions e file statici, variabili di build: su Workers li dichiari tu nel file Wrangler. Per chi usa Astro la scadenza la fissa l'adapter: da @astrojs/cloudflare v13, quella che serve per Astro 6, il deploy su Pages non è più supportato. Se resti su Astro 5 puoi aspettare. Se aggiorni, migri.
Pages e Workers, in due righe
Cloudflare Pages è il servizio nato per siti statici e Jamstack, con build da Git e Pages Functions per la parte server. Cloudflare Workers è la piattaforma di calcolo serverless di Cloudflare, che oggi serve anche file statici tramite Workers Static Assets. Le due cose si sono avvicinate, ma non coincidono.
La domanda sbagliata
Non "Workers è meglio di Pages?". È: cosa faceva Pages al posto mio, e dove lo devo scrivere adesso?
Pages indovinava. Guardava se c'erano index.html e 404.html e decideva da solo se il tuo era un sito statico o una SPA. Dava un binding ASSETS già pronto. Eseguiva le Functions prima dei file statici. Su Workers nessuna di queste cose è automatica: la guida ufficiale di migrazione lo dice chiaramente, per evitare configurazioni sbagliate per caso.
Il costo dichiarato non cambia molto. Le richieste agli asset statici restano gratuite e le invocazioni costano come prima, secondo Cloudflare. Quello che cambia è il lavoro di configurazione, e chi lo fa.
Quando ti tocca farlo
Il motivo concreto, per un sito Astro, è la versione dell'adapter.
La documentazione di @astrojs/cloudflare è netta. Astro 6 richiede l'adapter v13 o successivo, e la v13 ha rimosso il supporto a Cloudflare Pages. Al 14 ottobre 2026 l'ultima versione su npm è la 14.3.4, che chiede Astro 7.2 o superiore e Wrangler 4.125 o superiore.
Quindi la decisione non è "migro o no". È "quando aggiorno Astro". Il sito statico che gira su Pages con Astro 5 non smette di funzionare domani. Ma ogni aggiornamento di Astro che vuoi fare passa da qui.
Cosa cambia: tabella rapida
Cosa | Su Pages | Su Workers |
|---|---|---|
Cartella di output |
|
|
Pagina 404 e SPA | Dedotte dai file presenti |
|
Binding agli asset |
|
|
Chi risponde prima | Functions, poi asset | Asset, poi Worker (salvo |
| Supportati | Supportati, ma solo sugli asset statici |
Variabili | Build e runtime condivise | Separate: le variabili di build vanno in Workers Builds |
Comandi |
|
|
Porta locale | 8788 | 8787 |
Dominio | Anche fuori da Cloudflare, via CNAME | Solo con nameserver su Cloudflare |
Preview | Automatiche per ogni branch |
|
La riga che fa più danni è la quinta. Ci torno sotto.
Prima di toccare il codice
Tre controlli che decidono quale strada prendi.
- Il sito è tutto statico? Se Astro prerende ogni pagina, non ti serve l'adapter. Ti basta un file Wrangler con la cartella degli asset.
- C'è una cartella `functions/`? Se usi Pages Functions fuori da Astro, vanno compilate in un Worker con
wrangler pages functions build. - Che versione di Astro hai? Con Astro 5 e adapter v12 il punto d'ingresso è un file generato. Con Astro 6 o superiore è un modulo dell'adapter. Le due guide ufficiali mostrano esempi diversi proprio per questo.
Aggiorna anche Wrangler: la guida di migrazione parte dalla v4. Se ti stai chiedendo se usare ancora Wrangler, ne ho parlato in cf al posto di Wrangler: per questi comandi Wrangler resta il riferimento della documentazione.
Caso 1: sito Astro statico
È il caso più semplice e il più comune per un blog. Niente adapter, niente main. Solo un wrangler.jsonc nella root.
{
"name": "mio-sito-astro",
"compatibility_date": "2026-10-14",
"assets": {
"directory": "./dist",
"not_found_handling": "404-page"
}
}not_found_handling: "404-page" serve se hai una src/pages/404.astro. Senza, Workers non la usa da solo, come faceva Pages.
Poi build e deploy, con i comandi della guida Astro di Cloudflare:
npx astro build
npx wrangler deploySe il binding ASSETS ti resta nel file per abitudine, toglilo. La guida avverte che vale solo quando c'è uno script Worker indicato da main.
Caso 2: Astro con rendering on demand
Qui entra l'adapter. Se parti da Astro 6 o successivo, la guida di deploy di Astro indica questa configurazione:
{
"main": "@astrojs/cloudflare/entrypoints/server",
"name": "mio-sito-astro",
"compatibility_date": "2026-10-14",
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
"assets": {
"binding": "ASSETS",
"directory": "./dist"
},
"observability": {
"enabled": true
}
}Con Astro 6 il file Wrangler diventa perfino opzionale per i progetti semplici: se non hai binding da dichiarare, l'adapter genera una configurazione di default. Io lo terrei comunque nel repo. Un file versionato si legge in review, una configurazione generata no.
Se sei ancora su Astro 5 con adapter v12, la guida di Cloudflare usa "main": "./dist/_worker.js/index.js" e chiede un file public/.assetsignore con _worker.js e _routes.json. Senza, lo script del Worker finisce tra gli asset pubblici.
Il codice che cambia con Astro 6
La migrazione di piattaforma arriva spesso insieme all'aggiornamento di Astro. Le modifiche al codice sono di Astro, non di Cloudflare, ma le fai nello stesso momento.
Astro.locals.runtime non esiste più. Le variabili e i binding si importano dal runtime:
// prima
const { env } = Astro.locals.runtime;
// adesso
import { env } from 'cloudflare:workers';L'oggetto cf si legge da Astro.request.cf. Il contesto di esecuzione, quello di waitUntil(), è in Astro.locals.cfContext. L'opzione workerEntryPoint dell'adapter è stata rimossa: un entrypoint custom si indica in main e si esporta come un Worker standard.
Due cambi meno visibili. astro dev ora gira su workerd, lo stesso runtime della produzione: le dipendenze CommonJS che prima passavano in sviluppo possono rompersi. E l'ambiente Cloudflare si sceglie al build, con CLOUDFLARE_ENV=staging astro build, non più al deploy con --env.
Cosa si rompe: header, redirect, variabili
Header e redirect sulle pagine SSR. _headers e _redirects funzionano anche su Workers, nella cartella public/. Ma la documentazione degli header è esplicita: non si applicano alle risposte generate dal Worker. Lo stesso vale per i redirect. Se una pagina è renderizzata on demand, CSP, X-Frame-Options o un 301 scritti lì non arrivano. Vanno impostati nel codice, o con Bulk Redirects per i redirect.
Limiti dei file. _redirects regge 2.000 redirect statici e 100 dinamici. _headers regge 100 regole. Se migri un sito vecchio con migliaia di URL storici, conta le righe prima.
Variabili di build. Su Pages le variabili impostate in dashboard valevano per build e runtime. Su Workers no. Se usi Workers Builds, le variabili che servono durante astro build vanno configurate nelle impostazioni della build. Quelle di runtime vanno in vars o come secret con wrangler secret put. Per lo sviluppo locale c'è .dev.vars, che resta fuori dal repo. Per il resto dei controlli su segreti e deploy vale la checklist del sito vibe-coded.
Ordine di risposta. Workers serve prima l'asset statico, se esiste, e solo dopo chiama il Worker. Se avevi un middleware di autenticazione o di log davanti a tutto, serve run_worker_first. Ogni richiesta che passa dal Worker conta come un'invocazione normale.
Trailing slash. Il default auto-trailing-slash risponde con un 307 verso la forma canonica. Controlla che i canonical e la sitemap usino la stessa forma, o ti ritrovi pagine doppie.
Il passaggio senza buio
Questo ordine, ricavato dalla guida di Cloudflare, tiene in piedi il sito vecchio fino all'ultimo.
- Crea il Worker e deployalo su
workers.dev, senza toccare il dominio. - Confronta le pagine critiche: home, un articolo, la 404, un redirect vecchio, gli header di una pagina SSR.
- Collega il repo a Workers Builds e disattiva i deploy automatici del progetto Pages.
- Sposta il dominio custom sul Worker.
- Solo dopo giorni senza sorprese, cancella il progetto Pages con
wrangler pages project delete.
Il comando per il controllo a secco esiste e conviene lanciarlo prima del primo deploy vero:
npx wrangler deploy --dry-runQuando non ti conviene ancora
Ci sono casi in cui restare su Pages è la scelta onesta, almeno per ora.
- Il dominio non è su Cloudflare. Pages accetta un dominio custom via CNAME anche fuori dalla zona Cloudflare. Workers no: servono i nameserver su Cloudflare.
- Usi molto i controlli sui branch. La matrice di compatibilità segna i Branch Deploy Controls come supportati solo in parte su Workers.
- Hai un sito Astro 5 statico che non tocchi da mesi. Funziona, non ha binding, non ha SSR. La migrazione ha senso quando aggiorni Astro, non prima.
- Hai tante Pages Functions con routing a file. Si compilano in un Worker, ma Cloudflare stessa suggerisce di valutare un framework come HonoX se vuoi tenere quel modello.
Cosa guadagni spostandoti
Il guadagno vero non è il deploy. Sono le funzioni che su Pages non hai.
La matrice di compatibilità segna come solo Workers: Gradual Deployments, Workers Logs, Logpush, Tail Workers, Source Maps, Cron Triggers, consumer di Queues, Email Workers e il binding di Rate Limiting. Se ti serviva limitare un endpoint, ne ho scritto in rate limiting su Workers. E i Durable Objects si usano direttamente, senza un Worker separato da collegare.
Se il sito ha un database D1, controlla prima i backup di D1. I binding si ridichiarano nel file Wrangler. Conviene sapere dove sono i dati prima di spostare tutto.
Cosa conviene fare adesso
Apri il progetto e rispondi alle tre domande: statico o on demand, functions/ sì o no, Astro 5 o 6 e oltre. Poi scrivi il wrangler.jsonc del tuo caso, lancia wrangler deploy --dry-run e fai il primo deploy su workers.dev.
Prima di spostare il dominio, controlla header e redirect sulle pagine SSR. È lì che la migrazione fallisce in silenzio.
Domande frequenti
01Cloudflare Pages è deprecato?
La documentazione non lo dice. Cloudflare consiglia Workers per i progetti nuovi e offre una guida di migrazione per quelli esistenti. Per Astro il punto è un altro: l'adapter dalla v13 non supporta più Pages.
02Devo per forza usare l'adapter Cloudflare?
No, se il sito è tutto statico. Astro prerende le pagine e Workers serve la cartella dist. L'adapter serve solo per rendering on demand, server islands, actions e sessions.
03I miei _headers di sicurezza valgono ancora?
Sugli asset statici sì. Sulle pagine renderizzate dal Worker no: gli header vanno aggiunti nel codice, per esempio in un middleware Astro.
04Cambia il costo?
Secondo Cloudflare la struttura è simile: asset statici gratuiti, invocazioni al prezzo dei Workers. Cambia se attivi run_worker_first, perché ogni richiesta passa dal Worker e conta come invocazione.



