Il mio blog, ⌘+F e il podcast ⌘+P ora funzionano con Sanity invece che con Hygraph. Cosa ha motivato il passaggio, cosa continuo ad apprezzare di Hygraph, dove Sanity non è migliore e la checklist che uso oggi per scegliere un CMS.
Ci sono migrazioni che si rimandano proprio perché tutto funziona. Il mio sito andava. Gli articoli uscivano in più lingue, il podcast ⌘+P aveva i suoi feed RSS, ⌘+F la sua vetrina. Hygraph faceva il suo lavoro.
Eppure, eccoci qui: clementsauvage.me, cmdf.io e il podcast ⌘+P ora funzionano in produzione su Sanity. Un solo progetto, un solo modello di contenuto, sette lingue.
Questo articolo non è «Hygraph fa schifo, Sanity è fantastico». Hygraph mi è stato utile e resta un’ottima scelta per alcune esigenze. È il racconto di un cambiamento di priorità, con due cause molto concrete — il costo e l’IA — e una riflessione più ampia su come un imprenditore dovrebbe scegliere (e lasciare) un servizio SaaS nel 2026.
Il punto di partenza: uno stack che funzionava
Prima usavo:
- Hygraph come CMS headless, con GraphQL nativo
- Next.js 16 (App Router, Turbopack), Tailwind v4
- Apollo Client per interrogare l’API GraphQL
- next-intl per gestire sette lingue
- Clever Cloud Cellar (S3) dietro Cloudflare per alcuni file, Mux per i video
Niente di esotico. Uno stack moderno e pulito che fino a pochi mesi fa consigliavo ancora ai clienti.
Il problema non è nato da un bug. È nato dall’evoluzione: più lingue, più contenuti, più siti e un modo di lavorare sempre più basato sugli agenti IA. A ogni passo Hygraph mi costava un po’ di più, in denaro o in attrito.

Il mio vecchio editor Hygraph: titoli e sottotitoli in francese e inglese di «La ricetta per una grande app iOS», nello stesso contenuto. Schermata del mio progetto, ottobre 2026.
Primo motivo: il costo, soprattutto quello delle lingue
Sette lingue, in un piano tariffario pensato per due o tre
È questo che ha messo in moto tutto. Pubblico almeno in francese e in inglese, e il mio front-end gestisce sette lingue. Con Hygraph, la localizzazione è una risorsa tariffata per fasce:
- Il piano gratuito Hobby include 2 lingue.
- Growth parte da 199 $ al mese e include 3 lingue.
- Oltre, si entra nel territorio delle opzioni e di Enterprise, con preventivo (fino a 80 lingue).
Per un autore indipendente o una piccola realtà che vuole farsi leggere in più lingue, è un muro. Il multilinguismo non è un lusso per le aziende del CAC 40: è la quotidianità di qualunque realtà europea. Vederlo fatturato come opzione premium mi sembra un controsenso.

Le lingue del mio progetto Hygraph: francese predefinito, inglese e il limite del piano già raggiunto con queste due lingue. Schermata del mio progetto, ottobre 2026.
Il salto al piano Pro
Il passaggio dal gratuito al pagamento è il secondo scoglio. Hobby è generoso su alcuni aspetti, ma offre un solo ambiente. Appena vuoi un vero staging per provare una modifica allo schema senza rischiare la produzione, devi salire di piano. Passare di colpo da zero a 199 $ al mese per un’esigenza basilare come un ambiente di pre-produzione non ha un buon rapporto qualità-prezzo per un sito personale e due progetti comunitari.
Quote API e traffico degli asset
Terzo attrito, meno evidente: le quote.
- 500.000 operazioni API al mese con Hobby, un milione con Growth. Sembrano tante, finché non moltiplichi lingue, pagine generate, feed RSS del podcast ricreati regolarmente e build di anteprima.
- 100 GB di traffico per gli asset con Hobby. Le copertine del podcast, le immagini degli articoli e i visual di ⌘+F finiscono per pesare.
Preso singolarmente, nessuno di questi limiti è assurdo. Insieme, con tre siti che avrebbero dovuto essere tre progetti Hygraph, producono una fattura che cresce più in fretta del pubblico.
Cosa cambia con Sanity
Con Sanity, il quadro è diverso:
- Prezzo — Hygraph Hobby: 0 $; Sanity Free: 0 $.
- Lingue — Hygraph Hobby: 2; Sanity Free: senza limiti di numero*.
- Posti — Hygraph Hobby: 3; Sanity Free: 20.
- Ambienti / dataset — Hygraph Hobby: 1; Sanity Free: 2 (produzione + staging).
- Richieste API — Hygraph Hobby: 500.000 operazioni al mese; Sanity Free: 1 milione di richieste CDN + 250.000 richieste API al mese.
- Asset — Hygraph Hobby: 100 GB di traffico; Sanity Free: 100 GB di archiviazione + 100 GB di banda.
* Sanity non conta le lingue, ma gli «attributi unici» per dataset (2.000 nel piano Free, 10.000 in Growth). Con una localizzazione a livello di campo, ogni lingua moltiplica i percorsi degli attributi: è il limite da tenere d’occhio. Ci torno più avanti.
I prezzi sono quelli di fine settembre 2026, rilevati sulle pagine ufficiali di Hygraph e Sanity. Cambiano spesso: verificate prima di decidere.
Quando il piano Free non basta più, Growth di Sanity costa 15 $ per utente al mese. Per un team di due o tre persone siamo lontani dai 199 $ di partenza di Hygraph Growth, con tutte le lingue.
Secondo motivo: l’IA, o il CMS come strumento per gli agenti
Il costo mi ha spinto a guardarmi intorno. L’IA mi ha fatto scegliere Sanity.
Il mio modo di scrivere è cambiato. Redigo, traduco, rivedo e pubblico sempre più spesso con agenti — Claude, Codex — che lavorano sul mio codice e sui miei contenuti. La domanda non è più «l’interfaccia di editing è bella?», ma: il mio agente riesce a capire e manipolare i contenuti bene quanto me?
Su questo fronte, Sanity è un passo avanti.
Il server MCP: scrivere nel CMS da Claude o Codex
Sanity offre un server MCP ufficiale, ospitato su https://mcp.sanity.io. Per collegarlo basta eseguire npx sanity@latest mcp configure. Il comando rileva l’editor (Claude Code, Cursor, VS Code) e configura la connessione con le credenziali della CLI. Per Claude Code si può aggiungere manualmente il server con claude mcp add Sanity -t http https://mcp.sanity.io --scope user.
Da lì, l’agente può interrogare i contenuti in GROQ conoscendo lo schema, creare, modificare, pubblicare e ritirare documenti, gestire release, caricare asset da un URL e distribuire lo schema.
Il mio flusso è questo: lavoro a un articolo con l’agente, lo rileggo e l’agente crea direttamente una bozza in Sanity con i campi, i tag e le traduzioni giusti. Controllo tutto nello Studio e pubblico. Niente più copia e incolla tra un editor Markdown e un’interfaccia web.
Tradurre in sette lingue
Con sette lingue, la traduzione non è un dettaglio: è metà del lavoro editoriale. Grazie a MCP e alle funzioni IA integrate di Sanity (AI Assist, Agent Actions), posso generare una prima versione per ogni lingua e poi farla rivedere. L’IA fa il grosso; l’ultima parola spetta alla persona, soprattutto per il tono e i termini tecnici.

Il mio Sanity Studio: l’elenco degli articoli di clementsauvage.me e i titoli in francese e inglese raccolti nello stesso documento. Schermata del mio progetto, ottobre 2026.
Schemi leggibili dall’IA
È l’argomento più sottovalutato. Con Sanity, il modello dei contenuti è codice TypeScript, versionato nel repository. Quando un agente apre il progetto, vede insieme il front-end Next.js, le query e la definizione esatta di ogni tipo di documento. Non deve «scoprire» il modello nell’interfaccia web: lo legge come il resto del codice.
Per chi ama gli strumenti no-code è uno svantaggio (ci torno). Per un agente è un vantaggio decisivo: tutto il contesto è nello stesso posto.
Cosa è cambiato tecnicamente con la migrazione
La localizzazione a livello di campo
Ho scelto la localizzazione a livello di campo: un documento per articolo, con campi che contengono un valore per lingua. Il plugin ufficiale sanity-plugin-internationalized-array fa il lavoro.
La configurazione usa la lista delle lingue in i18n/locales, la stessa fonte di next-intl, e localizza i campi string e text. Nello schema, title ed excerpt diventano rispettivamente internationalizedArrayString e internationalizedArrayText. Lo slug deriva dal titolo francese; data di pubblicazione e copertina restano condivise. Il plugin visualizza i codici delle lingue in maiuscolo.
// sanity.config.ts
import { defineConfig } from 'sanity'
import { internationalizedArray } from 'sanity-plugin-internationalized-array'
import { LOCALES } from './i18n/locales'
export default defineConfig({
plugins: [
internationalizedArray({
languages: LOCALES.map((id) => ({ id, title: id.toUpperCase() })),
fieldTypes: ['string', 'text'],
}),
],
})
// schemas/post.ts
import { defineType, defineField } from 'sanity'
export const post = defineType({
name: 'post',
title: 'Article',
type: 'document',
fields: [
defineField({ name: 'title', type: 'internationalizedArrayString' }),
defineField({ name: 'excerpt', type: 'internationalizedArrayText' }),
defineField({
name: 'slug',
type: 'slug',
options: { source: (doc: any) => doc.title?.find((t: any) => t.language === 'fr')?.value },
}),
defineField({ name: 'publishedAt', type: 'datetime' }),
defineField({ name: 'cover', type: 'image', options: { hotspot: true } }),
],
})
Perché localizzare i campi invece di creare un documento per lingua? I miei articoli condividono quasi tutto — data, immagini, tag, autori — e cambiano solo i testi. Un documento è un’unica fonte di verità, e un agente che traduce deve modificare un solo oggetto.
Un dettaglio che può costare una serata: dalla versione 5 del plugin, la lingua è memorizzata in un campo chiamato language, non più in _key. I vecchi esempi online che usano _key == "fr" non funzionano più.
Da Apollo e GraphQL a GROQ
È stata la parte più impegnativa del lavoro sul front-end. Ho abbandonato Apollo Client per next-sanity, GROQ e TypeGen.
Prima, con Hygraph, Apollo eseguiva una query GraphQL per recuperare gli ultimi dieci post: posts(locales: [$locale, fr], orderBy: publishedAt_DESC, first: 10), con titolo, slug, excerpt e URL della copertina. Poi client.query passava locale come variabile.
Dopo, next-sanity usa GROQ per cercare i documenti di tipo post con slug.current definito, ordinati per publishedAt decrescente e limitati a dieci. La proiezione seleziona titolo ed excerpt con coalesce: prima la lingua richiesta, poi il francese come fallback. Restituisce slug.current e cover.asset->url. La chiamata è client.fetch(POSTS_QUERY, { locale }).
// Prima: Apollo + GraphQL di Hygraph
const GET_POSTS = gql`
query Posts($locale: Locale!) {
posts(locales: [$locale, fr], orderBy: publishedAt_DESC, first: 10) {
title
slug
excerpt
coverImage { url }
}
}
`
const { data } = await client.query({ query: GET_POSTS, variables: { locale } })
// Dopo: next-sanity + GROQ
import { defineQuery } from 'next-sanity'
export const POSTS_QUERY = defineQuery(`
*[_type == "post" && defined(slug.current)] | order(publishedAt desc)[0...10]{
"title": coalesce(title[language == $locale][0].value, title[language == "fr"][0].value),
"excerpt": coalesce(excerpt[language == $locale][0].value, excerpt[language == "fr"][0].value),
"slug": slug.current,
"cover": cover.asset->url
}
`)
const posts = await client.fetch(POSTS_QUERY, { locale })
Poi:
npx sanity typegen generate
TypeGen genera i tipi TypeScript dallo schema e dalle query. Il risultato è tipizzato da un capo all’altro, senza scrivere a mano neanche un’interfaccia.
Cosa ho guadagnato: meno dipendenze (niente Apollo né cache client da configurare), un fallback linguistico scritto direttamente nella query con coalesce e proiezioni che restituiscono esattamente la forma attesa dal componente.
Cosa riconosco a Hygraph
Sarebbe disonesto fermarsi qui. Hygraph ha punti di forza reali, e alcuni mi mancano.
- GraphQL nativo. È uno standard che tutto il team conosce, con strumenti maturi, e non vincola a un linguaggio proprietario.
- Localizzazione nativa. Con Hygraph le lingue sono una funzionalità di primo livello: scegli una lingua e ogni campo diventa localizzabile. Nessun plugin, nessuna configurazione. Più semplice — semplicemente costa caro.
- Schema builder no-code. Una persona non tecnica può far evolvere il modello dei contenuti dall’interfaccia. Con Sanity non si può fare senza passare dal codice.
- Content Federation. Collegare API esterne ed esporre tutto dietro un solo endpoint GraphQL è molto potente per un’azienda con dati sparsi. Non mi serviva, ma è un vero elemento distintivo.

Il modello Blog Post del mio progetto Hygraph: campi localizzati e tipi di campo disponibili nello schema builder. Schermata del mio progetto, ottobre 2026.
Se lavori in un team marketing di medie dimensioni, usi poche lingue, vuoi lasciare agli editor non tecnici autonomia sul modello e hai un budget CMS, Hygraph resta un’ottima scelta.
La mia obiezione riguarda un punto preciso: il suo modello tariffario penalizza le piccole realtà multilingue. È una scelta commerciale legittima, ma mi ha escluso dal suo pubblico di riferimento.
Dove Sanity non è migliore
La stessa onestà vale nell’altro senso.
GROQ bisogna impararlo. È un linguaggio proprietario. Una volta capito è potente, conciso e piacevole, ma lega le mie query a un CMS. Ho scambiato una dipendenza tariffaria con una dipendenza sintattica, consapevolmente. (Sanity offre anche una API GraphQL, ma così si perde una buona parte del vantaggio.)
Tutto passa dagli sviluppatori. Uno schema come codice è fantastico per chi sviluppa e per gli agenti. Per un editor non tecnico che vuole aggiungere un campo, la porta è chiusa. Nel mio caso sono io lo sviluppatore, quindi il problema non si pone. In un team potrebbe porsi eccome.
L’internazionalizzazione è meno nativa. Bisogna scegliere una strategia (campo o documento), installare un plugin, gestire le migrazioni di versione (il famoso passaggio da _key a language) e tenere d’occhio il limite degli attributi unici del dataset, che con sette lingue e la localizzazione a livello di campo può arrivare in fretta. Nulla di insormontabile, ma Hygraph fa questo lavoro al posto tuo.
Oltre il CMS: scegliere (e lasciare) un SaaS nel 2026
Questa migrazione mi ha ricordato soprattutto una cosa: uno strumento non è una scelta definitiva, ma una scelta valida in un determinato momento. Hygraph era la scelta giusta quando ho avviato lo stack. Quando le esigenze sono cambiate, non lo era più.
Tre lezioni che porto con me e condivido con i clienti.
1. Calcola i costi lungo il percorso, non solo sulla situazione di oggi. I piani tariffari sono pensati per rendere indolore l’inizio. Chiediti quanto costerà con il doppio delle lingue, dei contenuti, dei siti o dei collaboratori. È lì che emergono le differenze.
2. Nel 2026 «l’agente può usarlo?» è un criterio di primo piano. Uno strumento con un server MCP ufficiale, un modello leggibile nel codice e una API scriptabile ti farà risparmiare ore ogni settimana. Uno strumento controllabile solo con il mouse diventerà un collo di bottiglia.
3. Mantieni portabili i tuoi contenuti. Ho potuto migrare perché i contenuti erano strutturati e controllavo il front-end. Quando cambi strumento, la qualità del modello dei contenuti determina se la migrazione richiederà una settimana o tre mesi.
Checklist per scegliere un CMS headless
Queste sono le domande che mi faccio oggi, per me e per i miei clienti.
Contenuti e lingue
- ☐ Quante lingue servono oggi? E fra due anni?
- ☐ La localizzazione è inclusa, limitata o fatturata per lingua?
- ☐ Avviene a livello di campo, di documento o in entrambi i modi?
Costi
- ☐ Quanto costa il piano successivo e cosa lo fa scattare (utenti, lingue, ambienti, quote)?
- ☐ Come vengono conteggiate le chiamate API e cosa succede se si supera il limite?
- ☐ Un ambiente di staging è incluso già nel piano gratuito?
Team
- ☐ Chi fa evolvere il modello dei contenuti: uno sviluppatore o un editor?
- ☐ Serve la collaborazione in tempo reale?
Sviluppo
- ☐ Lo schema vive nel codice, versionato insieme al front-end?
- ☐ Linguaggio di query standard (GraphQL) o proprietario (GROQ…): sei disposto a impararlo?
- ☐ I tipi vengono generati automaticamente?
IA e agenti
- ☐ Esiste un server MCP ufficiale?
- ☐ Un agente può leggere lo schema, creare, modificare e pubblicare contenuti?
- ☐ Ci sono strumenti integrati di traduzione o generazione? A che costo?
Uscita
- ☐ Si può esportare tutto il contenuto in un formato aperto?
- ☐ Quanto costerebbe migrare fra due anni?
Rispondendo prima di scegliere, eviterai la maggior parte delle sorprese. Se rispondi dopo, come ho fatto io, almeno saprai quando è ora di andartene.
E adesso?
Tutto il mio ecosistema vive ora in un unico progetto Sanity: gli articoli del blog, i contenuti di ⌘+F e gli episodi di ⌘+P. Un modello, sette lingue e agenti che lavorano direttamente nel CMS.
Oggi consiglio Sanity anche ai miei clienti. Tre hanno già fatto il passaggio. La migrazione dei modelli di contenuto e di diverse migliaia di pagine ha richiesto solo poche ore — una decina per i progetti più grandi. Alcuni hanno recuperato il costo della migrazione in tre mesi.
Se hai dubbi sul tuo stack di contenuti, stai pensando a una migrazione o vuoi collegare gli agenti IA al tuo CMS, è proprio il tipo di progetto che seguo con BNC Consulting. Scrivimi.
E se vuoi parlarne con altri sviluppatori, unisciti alla community ⌘+F: condividiamo esperienze così anche ai meetup, davanti a un caffè o a cena.
— Clément
