SEO su Drupal: configurazione, moduli ed errori da evitare

Drupal non nasce con una configurazione SEO pronta all'uso come molti temi WordPress. È un framework di gestione contenuti pensato per la flessibilità - tipi di contenuto personalizzati, taxonomy, views generate a runtime - e questa stessa flessibilità è la ragione per cui, senza intervento, produce URL poco leggibili, meta tag assenti o duplicati e pagine di listato che si sovrappongono tra loro. In Italia lo si trova spesso dietro siti di comuni, università, enti regionali e portali della pubblica amministrazione, dove le migrazioni sono rare e la configurazione iniziale resta quella per anni, a volte impostata da un fornitore diverso da chi oggi se ne occupa.
Questo articolo non è un'introduzione generale alla SEO: assume che tu sappia già cosa sono un tag canonical o un redirect 301, e si concentra su cosa cambia quando il CMS è Drupal. Vediamo nell'ordine giusto: alias dei percorsi, moduli per meta tag e redirect, generazione della sitemap XML, e il problema specifico dei duplicati creati da taxonomy e views - la parte che più spesso viene trascurata perché non è un errore di configurazione isolato ma una conseguenza diretta di come Drupal organizza i contenuti.
Perché Drupal ha bisogno di una configurazione SEO dedicata
Drupal costruisce le pagine a partire da entità - nodi, termini di taxonomy, view - e di serie le espone con percorsi tecnici come /node/123 o /taxonomy/term/45. Non c'è un title tag pensato per la ricerca, non c'è un canonical automatico coerente con l'alias, e non esiste una sitemap XML finché non la installi. Tutto questo non è un difetto: è la conseguenza di un CMS pensato prima come framework per costruire strutture di contenuto arbitrarie, e solo dopo come piattaforma editoriale con un'uscita pubblica.
La conseguenza pratica è che ogni installazione Drupal richiede una checklist di moduli contrib e di decisioni di configurazione prima di poter competere in SERP con un sito WordPress con un tema SEO-ready. Su un'installazione headless o decoupled, dove Drupal fa solo da backend e il frontend è un'app separata (spesso in React o Next.js), la lista si allunga ulteriormente: anche se gli alias e i meta tag sono configurati correttamente nel backend, il frontend deve effettivamente restituirli nell'HTML servito al crawler, non solo dopo l'esecuzione di JavaScript.
- Alias leggibili al posto di node/ID e taxonomy/term/ID
- Gestione centralizzata di title tag, meta description e canonical
- Sitemap XML generata e aggiornata automaticamente
- Redirect coerenti quando un percorso cambia
- Nessuna pagina duplicata generata da tag multipli o filtri delle view
Alias degli URL con il modulo Pathauto
Pathauto, insieme al modulo Token da cui dipende, genera automaticamente l'alias di un nodo appena viene salvato, seguendo un pattern che definisci per tipo di contenuto: ad esempio /notizie/[node:title] per le notizie o /eventi/[node:field-data]/[node:title] per gli eventi. Senza Pathauto attivo, o su contenuti creati prima della sua attivazione, l'URL pubblico resta /node/123: funziona, ma non comunica nulla al lettore né al motore di ricerca, e complica ogni analisi successiva dei log o del posizionamento per singola pagina.
Il punto che più spesso viene sbagliato è la gestione dei duplicati di titolo. Se due notizie diverse si chiamano entrambe "Avviso pubblico", Pathauto per default genera /notizie/avviso-pubblico e poi /notizie/avviso-pubblico-0, /notizie/avviso-pubblico-1 e così via. Sono alias validi e univoci, ma comunicano poco e vanno quasi sempre corretti a mano includendo un elemento distintivo nel pattern - una data, il numero di protocollo, l'ente emittente - invece di lasciare che il suffisso numerico faccia da unica differenza.
Un secondo punto tecnico da non ignorare è la normalizzazione del case e dei caratteri accentati. Drupal, di default, non forza gli alias in minuscolo: un titolo con iniziali maiuscole può produrre un alias con maiuscole al suo interno, e se qualcosa nel sistema genera anche una variante minuscola dello stesso percorso, hai due URL tecnicamente diversi che portano allo stesso contenuto - un problema di duplicazione silenzioso che il canonical tag da solo non sempre risolve, perché nel frattempo entrambe le varianti possono essere state linkate internamente in punti diversi del sito.
- Un pattern per tipo di contenuto, non un pattern generico uguale per tutto il sito
- Transliterazione attiva per accenti e caratteri speciali, frequente nei toponimi italiani
- Alias forzati in minuscolo per evitare varianti duplicate dello stesso URL
- Rigenerazione massiva tramite l'azione bulk di Pathauto quando cambi un pattern, mai a mano su siti con migliaia di nodi
Meta tag e Open Graph con il modulo Metatag
Metatag centralizza title tag, meta description, Open Graph e canonical, con configurazioni di default per ogni combinazione di tipo di entità e bundle, costruite con token come [node:title] o [site:name]. Ogni nodo può poi sovrascrivere questi valori nel proprio form di modifica, dove Metatag aggiunge un fieldset dedicato: utile per le pagine chiave - home, pagine istituzionali, landing di servizio - dove vuoi un controllo editoriale fine, mentre per le migliaia di pagine secondarie il pattern di default fa il lavoro.
L'errore più comune è impostare una meta description statica identica per tutti i contenuti di un bundle, ad esempio lo stesso testo per centinaia di pagine di "Avviso". Google la ignora quasi sempre in questi casi e ne genera una propria dallo snippet di pagina, il che vanifica il lavoro fatto. Un pattern che pesca dal campo riassunto del nodo, se il tipo di contenuto ne ha uno, produce una meta description diversa per ogni pagina con lo stesso sforzo di configurazione.
Verifica anche che il canonical gestito da Metatag sia attivo su ogni bundle, incluse le pagine di taxonomy e le view, e che punti sempre all'alias e non al percorso interno node/ID. Su siti con più domini configurati (per esempio un dominio di test ancora raggiungibile, o un setup a più siti con Domain Access) il canonical generato di default può puntare al dominio sbagliato se il base URL non è impostato correttamente nella configurazione del sito: un dettaglio che passa inosservato finché non lo controlli esplicitamente in Search Console.
- Meta description dinamica dal campo riassunto, non un testo fisso ripetuto su tutte le pagine di un bundle
- Canonical attivo per ogni bundle, incluse le pagine taxonomy e le view
- Immagine Open Graph di default per i nodi senza immagine in evidenza propria
- Override manuale riservato alle pagine editorialmente più importanti
Redirect e gestione degli errori 404
Il modulo Redirect mantiene una tabella di mapping tra vecchi percorsi e nuovi, applicando 301 o 302 secondo la configurazione. La combinazione utile con Pathauto è l'opzione che crea automaticamente un redirect quando un alias esistente viene rigenerato o modificato: senza attivarla, ogni volta che cambi un pattern o rinomini un contenuto, il vecchio URL indicizzato inizia a restituire 404 e resta così finché Google non ricrawla e aggiorna l'indice, con una perdita temporanea ma reale di traffico su quella pagina.
Nelle migrazioni da un altro CMS - Joomla, un vecchio sito statico, o una versione precedente di Drupal - il modulo Redirect accetta un import massivo da file CSV con vecchio percorso e nuovo alias su due colonne. È il modo corretto di consolidare il segnale di posizionamento accumulato dalle pagine storiche, invece di lasciare che scadano tutte in 404 e sperare che gli utenti trovino la nuova struttura da soli.
Il report incluso in Drupal per gli errori "pagina non trovata" (nel percorso amministrativo dei report) registra ogni 404 nella tabella dei log di sistema, ma su un sito con traffico sostenuto quella tabella ruota rapidamente e le voci più vecchie vengono sovrascritte prima che qualcuno le controlli. Vale la pena rivederlo con una cadenza fissa, non a campagna finita, e affiancarlo alle impostazioni dello stesso Redirect, che nelle versioni moderne di Drupal ha assorbito le funzioni del vecchio Global Redirect, per forzare un'unica combinazione di host, protocollo https e barra finale: senza questa normalizzazione, varianti come esempio.it/pagina ed esempio.it/pagina/ possono comportarsi come URL distinti agli occhi del crawler.
- Redirect automatico alla modifica dell'alias, per non perdere il segnale del vecchio URL già indicizzato
- Import CSV dei redirect nelle migrazioni, mappando ogni vecchio percorso al nuovo alias
- Controllo periodico del report "pagina non trovata" prima che il log ruoti
- Normalizzazione di host, https e barra finale a livello di modulo, non lasciata al caso
Sitemap XML: generazione e invio a Google
Il modulo Simple XML Sitemap (l'evoluzione del vecchio XML sitemap per le versioni più recenti di Drupal) genera il file a partire da una selezione esplicita di tipi di entità e bundle da includere: di norma vanno esclusi i tipi di contenuto puramente amministrativi e qualunque nodo non pubblicato, che altrimenti finirebbe elencato pur non essendo raggiungibile pubblicamente. I campi priority e changefreq sono configurabili ma Google li ignora da anni: non vale la pena passare tempo a calibrarli con precisione, la sitemap serve a far scoprire e confermare gli URL canonici, non a segnalare priorità di scansione.
Un punto spesso trascurato è che la generazione della sitemap dipende dal cron di Drupal, non è istantanea. Su hosting condiviso, dove il cron interno di Drupal viene richiamato solo da una visita casuale al sito o da un cron di sistema mal configurato, la sitemap può restare ferma a una versione vecchia per settimane mentre il sito continua a pubblicare contenuti nuovi che non ci finiscono dentro. Verificare che il cron sia effettivamente in esecuzione, e non solo abilitato nella configurazione, è un controllo da 30 secondi che evita di scoprire il problema mesi dopo guardando Search Console.
Per i siti multilingua, frequenti tra enti pubblici italiani con una versione in inglese o in una lingua di minoranza riconosciuta, Simple XML Sitemap genera una sitemap index con un file per lingua e collega automaticamente le varianti se la configurazione di language negotiation è coerente con i prefissi usati negli URL. Se il prefisso di lingua nell'URL non corrisponde a come il modulo si aspetta di trovarlo, il risultato è una sitemap che elenca URL con il prefisso sbagliato o che non collega correttamente le varianti linguistiche tra loro.
- Escludere dalla sitemap i tipi di contenuto amministrativi e i nodi non pubblicati
- Non investire tempo su priority e changefreq: Google li ignora
- Verificare che il cron sia realmente in esecuzione, non solo configurato
- Sitemap index per lingua sui siti multilingua, coerente con la configurazione di language negotiation
- Invio manuale in Search Console dopo ogni cambio strutturale importante, come un nuovo pattern di alias
Contenuti duplicati generati da taxonomy e views
Questo è il punto dove Drupal si comporta diversamente dagli altri CMS più comuni, ed è la ragione per cui vale un capitolo a parte. Ogni termine di taxonomy genera automaticamente una pagina di listato all'indirizzo /taxonomy/term/ID, che elenca i teaser di tutti i nodi con quel termine assegnato. Se un contenuto porta più tag - una notizia con tre categorie, per dire - lo stesso identico blocco di teaser compare su tre pagine di listato diverse, ciascuna delle quali è indicizzabile per default. Nessuna di queste pagine ha un testo introduttivo proprio: sono elenchi meccanici, e più termini condividono gli stessi nodi più le pagine si sovrappongono tra loro nel contenuto effettivamente visibile.
Le view esposte con filtri (categoria, data, tipo) aggiungono un secondo livello dello stesso problema, più difficile da individuare perché non riguarda le pagine principali del sito ma le combinazioni di parametri nell'URL. Se una view accetta filtri via query string e non limiti quali combinazioni sono raggiungibili, il crawler può trovarsi davanti a un numero enorme di URL del tipo /elenco?categoria=X&ordine=data, ciascuno quasi identico agli altri per contenuto ma tecnicamente unico per URL: è una delle cause più comuni di spreco di crawl budget su siti Drupal con cataloghi o elenchi pubblici estesi, dove il crawler continua a scoprire nuove combinazioni di filtro invece di concentrarsi sui contenuti che contano.
La decisione da prendere caso per caso è quale di queste pagine merita di restare indicizzata. Una pagina di taxonomy con un buon numero di contenuti e un testo introduttivo curato dall'editor può funzionare come vera pagina di categoria e vale la pena lasciarla indicizzabile. Una pagina di taxonomy quasi vuota, o che duplica al 90% un'altra pagina di taxonomy per sovrapposizione di tag, è meglio impostarla in noindex tramite l'override di Metatag condizionato al bundle, oppure farle puntare con un canonical a una pagina di categoria più ricca se ne esiste una editorialmente curata. Per le combinazioni di filtro delle view, la soluzione tipica è impedirne la scansione con una regola in robots.txt sui pattern di query string più comuni, mantenendo però il canonical della view filtrata puntato sulla versione senza filtro, così il valore si consolida lì invece di disperdersi su centinaia di varianti.
- Nodi con tag multipli compaiono identici su più pagine taxonomy: valuta noindex o un canonical verso una pagina più ricca
- Filtri esposti nelle view generano combinazioni di query string potenzialmente infinite: limitane la scansione in robots.txt
- Canonical delle view filtrate puntato sulla versione senza filtro, per consolidare il segnale
- Pagine di paginazione delle view: canonical a se stesse quando il contenuto elencato cambia realmente pagina per pagina
- Vocabolari di taxonomy troppo granulari moltiplicano pagine di listato quasi vuote: valuta l'accorpamento dei termini con pochi nodi
Errori più comuni da evitare
Oltre alle decisioni di configurazione già viste, ci sono errori che si ripetono con una regolarità sorprendente tra installazioni diverse, di solito perché nessuno li verifica dopo il lancio iniziale del sito. Il modulo Devel, usato in sviluppo per generare contenuti fittizi con cui testare i template, viene talvolta lasciato attivo in produzione insieme ai nodi di test che ha creato: quei contenuti finiscono indicizzati, diluendo la qualità media percepita del sito agli occhi di un crawler che valuta il dominio nel suo insieme, non pagina per pagina in isolamento.
Un secondo errore ricorrente è un file robots.txt copiato da un progetto precedente, magari su un altro CMS, e mai adattato alla struttura reale di Drupal: blocca percorsi che non esistono più o, peggio, lascia scansionabili directory interne come /admin o percorsi di configurazione che non hanno alcun valore per la ricerca ma consumano budget di scansione. Va scritto - o almeno rivisto - pensando alla struttura effettiva del sito, non copiato per abitudine.
Infine, il percorso node/ID resta quasi sempre raggiungibile in parallelo all'alias anche dopo che Pathauto ha generato un URL leggibile, perché Drupal non lo disabilita di default: risolve allo stesso contenuto, il canonical dovrebbe indicare quale versione preferire, ma se il canonical non è configurato correttamente su tutti i bundle - il caso del capitolo sui meta tag - il crawler può trattarle come due pagine equivalenti invece di consolidare il segnale su una sola. Un redirect 301 esplicito da node/ID all'alias, dove tecnicamente praticabile, è più robusto di un canonical da solo perché rimuove la seconda versione dalla scansione invece di limitarsi a segnalarla come secondaria.
- Devel e contenuti dimostrativi lasciati attivi in produzione e finiti indicizzati per errore
- robots.txt ereditato da un altro progetto e mai adattato alla struttura reale di Drupal
- Percorso node/ID ancora raggiungibile in parallelo all'alias senza un canonical o un redirect che consolidi il segnale
- Ambiente di staging su sottodominio lasciato scansionabile insieme al sito di produzione
- hreflang non allineato alla configurazione reale di language negotiation nei siti multilingua
Domande frequenti
Esiste un modulo SEO unico per Drupal, come Yoast per WordPress?
No, non c'è un equivalente diretto. La stessa funzionalità si ottiene componendo moduli indipendenti - Pathauto per gli alias, Metatag per title e meta description, Redirect per i reindirizzamenti, Simple XML Sitemap per la sitemap - ciascuno configurabile separatamente per tipo di contenuto.
Cambiare il pattern degli alias in Pathauto rompe gli URL già indicizzati?
Non se attivi l'opzione che crea automaticamente un redirect quando l'alias di un contenuto cambia. Senza quell'opzione, il vecchio URL indicizzato restituisce 404 fino al successivo ricrawl di Google.
Le pagine di taxonomy vanno sempre messe in noindex?
Dipende dal contenuto che elencano. Una pagina con un buon numero di nodi e un testo introduttivo curato può restare indicizzata come vera pagina di categoria; una pagina quasi vuota o che si sovrappone quasi del tutto a un'altra per gli stessi tag è meglio metterla in noindex o farle puntare un canonical verso una pagina più ricca.
Un sito Drupal headless ha problemi SEO diversi da un'installazione tradizionale?
Sì. Se il frontend è renderizzato lato client, ad esempio con un'app React separata, Googlebot deve eseguire JavaScript per vedere il contenuto e i meta tag effettivi, quindi il rendering lato server o il pre-rendering della pagina diventa un controllo molto più critico che su un'installazione Drupal tradizionale dove l'HTML arriva già completo.
I campi priority e changefreq della sitemap XML influenzano il posizionamento?
No. Google li ignora da tempo: la sitemap serve a far scoprire e confermare gli URL canonici del sito, non a comunicare una priorità di scansione o di ranking.