Come è fatto il blog di ICT Sviluppo: Sanity headless, Nuxt su Azure e un'architettura a pillar, hub e spoke
Lo stack e il modello di contenuto del nostro blog: Sanity headless, Nuxt su Azure e un'architettura editoriale in cui ruoli, relazioni e CTA sono dati interrogabili invece di link scritti a mano.


Il blog di ICT Sviluppo arriva da una storia di blog ospitato sul dominio di ictsviluppo.it e vive di una migrazione parziale (il sito istituzionale è rimasto dov’era e viviamo con questo blog per due anni su un limbo, quindi tutto da reindirizzare e riposizionare… se vi chiedete come mai a livello SEO non sia così presente sulla SERP) con la maggioranza dei post dedicati al commercio elettronico e alcuno che esplorano il mondo digitale in senso più ampio; sta in piedi su tre pezzi: Sanity conserva i contenuti in un archivio documentale interrogabile, il framework Nuxt costruisce le pagine in server side rendering, Azure Static Web Apps le serve su blog.weareict.it, dove ogni pezzo risponde a un indirizzo della forma /post/slug.
La parte che si è rivelata decisiva, mentre gli articoli passavano da qualche decina a quasi cinquecento, è il modello di contenuto: la struttura dei campi con cui un articolo viene descritto, i ruoli che gli articoli hanno l'uno rispetto all'altro, le relazioni che li legano e il modo in cui tutto questo, essendo dato e non testo, si può interrogare.
Un archivio di cinquecento pezzi senza una struttura del genere non è un archivio, è un magazzino: le cose ci sono tutte e nessuno sa dove.
Quello che descrivo in questo post è l'impianto, raccontato per come lo usiamo ogni giorno, insieme ai numeri che lo descrivono adesso e a quello che questo modo di lavorare chiede in cambio a chi scrive.
Lo stack: Sanity per i contenuti, Nuxt per le pagine, Azure per servirle
Sanity è un CMS headless, cioè un sistema che conserva i contenuti e li espone via API senza avere opinioni su come vengano mostrati.
I documenti vivono in un archivio che si interroga con GROQ, il linguaggio di query di Sanity, e questa è la differenza che si sente nel lavoro quotidiano: una domanda come quali articoli non hanno ancora un ruolo assegnato, o quali linkano una certa pagina nel corpo del testo, è una query di tre righe e non un pomeriggio passato ad aprire pagine una per una. Su come è costruito il prodotto e cosa lo distingue dagli altri CMS abbiamo scritto un pezzo dedicato a che cos'è Sanity CMS, e uno che lo mette a confronto con WordPress sui progetti enterprise.
Il front end è un'applicazione Nuxt, quindi scritta con il framework Vue.js, che gira in server side rendering: la pagina arriva al browser e ai motori di ricerca già costruita, con il suo HTML completo, e non come uno scheletro che aspetta il JavaScript per riempirsi.
Per un blog che campa di ricerca organica e, sempre di più, di risposte generate dagli assistenti conversazionali, quella è la condizione perché il contenuto esista per chi lo legge senza eseguire codice.
L'hosting è Azure Static Web Apps, che serve il front end e ne ospita il middleware, cioè lo strato che intercetta le richieste prima che diventino pagine e decide, per esempio, quando rispondere con un reindirizzamento. Il vantaggio di tenere il CMS, il front end e l'hosting su tre fornitori distinti è che ognuno dei tre si cambia senza toccare gli altri due, e il difetto è esattamente lo stesso: sono tre contratti, tre pannelli di controllo e tre posti dove un problema può nascere.
Chi valuta un'architettura del genere per il proprio commercio elettronico, e non per un blog, trova il ragionamento completo nel pezzo su cos'è un ecommerce headless, dove i vantaggi stanno accanto ai costi.
Vale la pena dirlo con chiarezza, perché è il punto che viene sottovalutato più spesso: cambiare il sistema che tiene i contenuti significa spostare indirizzi, dati e posizionamento, e questo è un replatforming a tutti gli effetti, con tutta la disciplina che cambiare piattaforma richiede. I vecchi indirizzi del blog vengono ancora oggi reindirizzati con un 301 verso i nuovi, uno per uno, e non esiste versione di questo lavoro in cui quella tabella si possa saltare.

La redazione lavora in Sanity Studio, che è l'interfaccia di scrittura del CMS, ed è fatta di componenti sviluppati su misura sul nostro modello di contenuto: chi scrive vede i campi che servono a questo blog, nell'ordine in cui li deve compilare, e non un editor generico da riempire come viene.
Un articolo è un documento, non una pagina
Nel nostro schema un post ha un titolo, uno slug che ne determina l'indirizzo, un excerpt che fa da sottotitolo e resta sotto i duecento caratteri, un author scelto fra i sei della redazione, una category fra ecommerce e digital, una date, un blocco seo con titolo e descrizione per i motori, una mainImage con il suo testo alternativo, e un corpo.
Il corpo è Portable Text, e non un blocco unico di HTML: un array di blocchi in cui ogni paragrafo, ogni titoletto, ogni voce di elenco è un oggetto con un suo identificativo, e i link non sono tag annegati nel testo ma annotazioni separate, i markDefs, agganciate al pezzo di frase che le porta. La conseguenza pratica è quella che rende possibile tutto il resto di questo articolo: se un link è un dato, allora i link si contano. Sapere quanti articoli linkano una certa pagina dal corpo del testo, e quali sono, è una query; sapere quali blocchi promettono al lettore qualcosa che la destinazione non mantiene è una lettura di quei blocchi, non una caccia al tesoro fra cinquecento pagine.
Accanto a questi campi ce ne sono altri che non descrivono il testo ma il suo posto nell'archivio, e sono quelli che valgono il resto del discorso: tags, che porta i riferimenti alle etichette, family, che dice a quale famiglia il pezzo appartiene, role, che dice che lavoro fa, persona e stage, che dicono a chi parla e in che punto del percorso d'acquisto, e correlati, che sono sei riferimenti ad altri articoli.
Pillar, famiglia, hub e spoke: come è organizzato l'archivio
Il campo role ha quattro valori, e ognuno descrive un lavoro diverso. Il pillar è il contenuto canonico di un argomento, la pagina che vogliamo sia la risposta di riferimento su quel tema, e ce n'è esattamente uno per argomento: oggi tredici argomenti, tredici pillar.
L'hub è il capofila di una famiglia, cioè di un gruppo di contenuti che vivono dentro un argomento più ampio e hanno una domanda comune: mentre scrivo sono quarantasette hub per cinquantuno famiglie censite.
Lo spoke è l'approfondimento, il pezzo che scava una porzione della materia e rimanda al suo hub: alla data di oggi sono trecentocinquantuno, ed è giusto che siano la maggioranza.
La storia è il racconto, l'intervista, la puntata di un podcast, che non risponde a una domanda di ricerca e non finge di farlo.
Tre livelli, quindi, e non due: argomento, famiglia, pezzo.
La ragione per cui il livello intermedio esiste è empirica.
Con tredici argomenti soltanto, un pillar si trovava a dover distribuire link verso venti o trenta approfondimenti, e una pagina che manda il lettore in trenta direzioni diverse non lo sta guidando, lo sta smistando.
La famiglia raccoglie quello che davvero appartiene alla stessa domanda, le dà un capofila che quella domanda la risponde per intero, e lascia al pillar il compito di indirizzare verso le famiglie invece che verso i singoli pezzi.
Anche le pagine di lista seguono questa logica, ed è un criterio esplicito: le liste di argomento e di famiglia hanno una descrizione scritta a mano e un contenuto canonico indicato, quindi sono pagine vere e sono indicizzabili; le etichette tecniche, quelle che dicono soltanto con quale tecnologia o modello di business un pezzo ha a che fare, hanno una descrizione generata e restano fuori dall'indice. Il discriminante è se qualcuno ha scritto qualcosa su quella pagina, non il tipo di etichetta.
Perché argomenti e famiglie sono dati e non definizioni di schema
Questa è la decisione di prodotto di cui siamo più contenti, e all'inizio non era ovvia. I valori chiusi, cioè role, persona e stage, stanno nello schema: sono quattro, quattro e tre, cambiano quasi mai, e averli come liste chiuse impedisce a chi scrive di inventarsi un ruolo nuovo il venerdì sera. Gli argomenti e le famiglie, invece, sono documenti come gli altri, etichette con un campo che dichiara di che tipo sono, e questo significa che nascono, si rinominano e si riorganizzano via API in qualunque momento, senza toccare il codice del front end e senza aspettare il rilascio di nessuno.
Il conto è presto fatto: quarantasei famiglie sono nate nei dieci giorni di lavoro editoriale successivi al rilascio del campo che le rendeva possibili, e oggi sono cinquantuno; se ognuna fosse stata una voce in una lista dello schema, ognuna sarebbe stata un intervento di sviluppo. Averle come dati ha reso l'architettura una cosa che la redazione governa da sé.
Le quattro relazioni, e il fatto che si possano contare
Un archivio organizzato in tre livelli ha bisogno di regole precise su chi linka chi, altrimenti i link interni diventano quella maglia indistinta in cui tutto punta a tutto e nessuna pagina emerge. Le nostre sono quattro, e ognuna ha un verso:
- Lo spoke linka l'hub della sua famiglia, con un link contestuale dentro il corpo, nel punto in cui il discorso lo chiede.
- Lo spoke linka il pillar dell'argomento quando il tema affiora davvero, e non come obiettivo di copertura da riempire.
- Il pillar linka gli hub delle famiglie che gli stanno sotto.
- L'hub linka i suoi spoke, uno per uno, cedendo a ciascuno la porzione di materia che quel pezzo tratta meglio di lui.
La regola che tiene insieme le quattro è una sola, e riguarda l'onestà del link: la frase che introduce un link promette qualcosa a chi legge, e la pagina di destinazione quella promessa la deve mantenere. Un link rotto si trova con uno script; un link che porta a una pagina che non contiene quello che la frase annunciava non lo trova nessuno strumento, lo trova solo chi apre la destinazione e rilegge la frase intera. È il controllo più noioso di tutto il lavoro editoriale ed è quello che fa la differenza fra un percorso di lettura e un labirinto.
Poi ci sono le relazioni che non passano dal testo ma dai campi. Ogni articolo porta sei correlati, che sono riferimenti ad altri documenti e non URL scritti a mano, quindi se un pezzo viene rinominato o accorpato il riferimento resta valido invece di diventare un vicolo cieco. Sei è il numero, non un massimo: quando i candidati ovvi sono quattro si allarga all'argomento adiacente, perché un blocco di correlati mezzo vuoto è una pagina che ammette di non sapere dove mandare il lettore. Oggi 409 articoli su 493 li hanno tutti e sei, e 359 hanno la famiglia compilata.
Il vantaggio di avere tutto questo come dato, e non come consuetudine, è che l'architettura si verifica invece di essere raccontata. Quanti spoke di una famiglia non linkano il proprio hub, quali hub sono più magri dei pezzi che dovrebbero riassumere, quali articoli sono orfani, cioè non ricevono nemmeno un link dal corpo di un altro: sono tutte query, e una query che torna un numero diverso da quello atteso è un debito che si vede il giorno in cui nasce e non sei mesi dopo.
Le CTA sono documenti, non pulsanti scritti nel testo
Gli inviti all'azione, nel nostro schema, sono documenti a sé: tredici, ciascuno con il suo titolo e la sua destinazione. Dentro il corpo di un articolo non c'è un pulsante con un indirizzo dentro, c'è un blocco che fa riferimento a uno di quei tredici documenti. Il giorno in cui una pagina di atterraggio cambia indirizzo, si cambia il documento e cambiano insieme tutti gli articoli che lo citano, senza cercare pulsante per pulsante in cinquecento pagine.
La regola editoriale che ci siamo dati sopra a questo meccanismo è che ogni argomento ha la sua chiamata giusta, quella coerente con la ragione per cui una persona sta leggendo quel tipo di pezzo, e che un articolo con la chiamata sbagliata è un articolo che chiede la cosa storta al momento storto. Questo resta un giudizio nostro, tenuto in un registro di lavoro e non nello schema, perché è materia che cambia con l'offerta e non con il codice. Lo stato di oggi lo diciamo senza abbellirlo: 160 articoli su 493 portano una chiamata all'azione, gli altri no, ed è il debito più grosso che questo archivio ha.
Anche i reindirizzamenti stanno nel CMS
Quando due articoli si accorpano, o uno viene potato perché non ha più ragione di esistere, il suo indirizzo non deve diventare un errore: deve portare al pezzo che ne ha preso il posto. Nel nostro modello questo si fa con un documento dedicato, che dichiara l'indirizzo di partenza, quello di arrivo, se il reindirizzamento è permanente e se è attivo. Ne abbiamo quarantanove, tutti attivi, e nessuno di essi ha richiesto una riga di codice.
Il front end li legge e serve il 301, con una latenza di qualche istante fra la pubblicazione del documento e il momento in cui l'indirizzo vecchio comincia davvero a reindirizzare. È un comportamento normale, non un guasto, e sapere che esiste evita l'errore di chi verifica troppo presto, vede ancora la pagina vecchia rispondere e conclude che il meccanismo non funziona. La regola che ne abbiamo tratto è operativa: si verifica il 301 con una richiesta vera prima di togliere di mezzo la pagina di partenza, sempre, anche quando si è fatta la stessa operazione trenta volte.
Quanto è veloce e quanto è accessibile, misurato adesso
Su questa pagina, misurata oggi con Lighthouse su profilo desktop, il front end porta 96 su 100 di prestazioni, 96 di accessibilità, 100 di buone pratiche e 100 di SEO tecnica, con il contenuto principale disegnato in 0,79 secondi, uno spostamento cumulativo del layout di 0,01 e venticinque millesimi di secondo di blocco del thread principale. Sono numeri di un singolo rilevamento, non una media su settimane, e li scriviamo con la loro provenienza proprio perché i punteggi tondi dichiarati senza fonte non significano niente.
Sull'accessibilità il punteggio automatico è un pavimento e non un traguardo: gli strumenti verificano una parte dei criteri e nessuno di essi può dire se un testo alternativo descrive davvero l'immagine o se un contrasto è comodo per chi legge, e per il resto servono scelte prese a mano, dal contrasto dei colori all'assenza di riproduzioni automatiche. Su cosa chiede la norma a chi pubblica, e su come si lavora davvero sui criteri, abbiamo un pezzo dedicato all'accessibilità web.
Che disciplina chiede un'architettura così
Il costo di questo impianto si paga in disciplina, e non nel canone del CMS. Un articolo non è finito quando il testo è buono: è finito quando ha l'argomento, la famiglia, il ruolo, la persona a cui parla, il punto del percorso in cui la intercetta, i sei correlati, la chiamata all'azione giusta, il link al suo hub e il campo seo riscritto. Ogni casella vuota è un pezzo che sta nell'archivio senza starci dentro, e la prova che questa non è teoria è che ottanta articoli, oggi, non hanno ancora un ruolo assegnato: sono i più vecchi, arrivati con la migrazione, e li stiamo lavorando uno per uno.
Il secondo costo è il front end, che è un'applicazione nostra e come tale va mantenuta: gli aggiornamenti li facciamo noi, i componenti nuovi li sviluppiamo noi, e una funzione che su un CMS tradizionale si attiva con una spunta qui è codice da scrivere. Chi valuta se un contenuto editoriale abbia bisogno di un'architettura separata dal proprio negozio online trova il ragionamento, con la domanda su chi deve possedere la pagina, nel pezzo su quando serve un CMS headless per l'ecommerce; e chi vuole vedere lo stesso schema applicato a un negozio, con Sanity come testa editoriale accanto al motore di vendita, lo trova nel pezzo su Sanity e Shopify Plus.
Quello che ci ha restituito, in cambio, è la possibilità di fare domande all'archivio e ottenere risposte esatte. Un blog di cinquecento pezzi in cui nessuno sa quale sia la pagina di riferimento su un tema produce contenuti che si fanno concorrenza fra loro; lo stesso blog, con i ruoli e le relazioni scritti nei dati, produce percorsi di lettura. La differenza non la vede il lettore in una pagina singola, la vede quando arriva sulla seconda.
Domande frequenti
Serve un CMS headless per fare un blog?
No, e per la maggior parte dei blog non conviene: un CMS tradizionale fa il lavoro con meno pezzi e meno manutenzione. Conviene quando i contenuti sono tanti, quando devono essere descritti da campi propri e interrogabili, e quando servono anche fuori dal sito, per esempio dentro un'applicazione o su un altro canale. Se la domanda è soltanto pubblicare articoli, la risposta è che non serve.
Che differenza c'è fra pillar, hub e spoke?
Il pillar è il contenuto canonico di un argomento, e ce n'è uno solo per argomento. L'hub è il capofila di una famiglia dentro quell'argomento, e risponde per intero alla domanda comune dei pezzi che la compongono. Lo spoke approfondisce una porzione della materia e rimanda all'hub. La gerarchia serve a impedire che una sola pagina debba smistare i lettori in trenta direzioni.
Chi scrive deve conoscere il modello dati?
Deve conoscere le decisioni, non la loro implementazione. Chi scrive decide a chi parla il pezzo, in che punto del percorso lo intercetta, a quale famiglia appartiene e quale altro pezzo ne regge il seguito; l'interfaccia di scrittura presenta quelle scelte come campi da compilare, e a quel punto il modello dati è un dettaglio che sta sotto e non chiede attenzione.
Post correlati

Che cos'è Sanity CMS: il content operating system headless
Sanity è la piattaforma di gestione contenuti headless, oggi content operating system: cos'è, come funziona e perché conviene ai progetti middle market ed enterprise.

Headless ecommerce: cos'è, come funziona e quando ha senso
Back end e front end separati che dialogano via API: come funziona un ecommerce headless, di cosa è fatto lo stack, quanto costa e quando invece basta un tema Shopify ben costruito.

CMS headless per l'ecommerce: quando serve e chi possiede la pagina
Prima di scegliere un CMS headless conviene decidere chi possiede ogni pagina: cosa Shopify gestisce con i metaobject, le quattro configurazioni reali e il costo dello sdoppiamento.

Sanity e Shopify Plus per l'ecommerce headless
Come si costruisce un ecommerce headless con Shopify Plus e Sanity: architettura, integrazione, vantaggi e dove si colloca nella matrice di complessità del Metodo ICT.

Sanity CMS vs WordPress: quale CMS per progetti enterprise
Sanity CMS contro WordPress per progetti middle market ed enterprise: paradigmi, sicurezza, performance e costo totale a confronto, oltre i problemi dell'opensource.

Replatforming ecommerce: quando conviene cambiare piattaforma e quando no
Cos'è il replatforming, i segnali che è ora di cambiare piattaforma, i casi in cui non conviene affatto, i rischi veri e come si sceglie la destinazione.
