Indicizzazione Google: perché il 70% delle pagine non passa il filtro (caso studio su 105 URL)
L'audit dell'11 maggio 2026 ha tirato fuori un dato secco: 31 pagine INDEXED su 105 totali. Il 29,5%. Le altre 70 stanno in tre stati diversi che Google racconta in modo opaco a chi non passa giornate a leggere la documentazione di Search Console. Il punto è che la sitemap mente. Dice a Google "ecco 105 URL, indicizzali", e Google risponde con un mezzo silenzio.
Per otto mesi ho pubblicato pensando che fosse tutto in regola. Il sitemap c'era, le canonical pure, il robots.txt non bloccava niente. Quando il crawl budget è entrato come P0 nel piano SEO a inizio aprile, mi sono dovuto fermare e misurare. Non l'avevo mai fatto in modo sistematico. Ho tirato giù uno script che batte l'URL Inspection API di Google Search Console per ogni singolo URL del sitemap, e il risultato è stato che metà del lavoro editoriale degli ultimi otto mesi era opaco a Google.
Non è un problema di contenuto. È un problema di segnali.
Andiamo per ordine.
Cosa significa davvero "Discovered, currently not indexed"
Google Search Console restituisce per ogni URL uno stato di indicizzazione. I tre principali da conoscere prima di toccare qualsiasi fix:
- INDEXED. Google ha la pagina nel suo indice. Può apparire nelle ricerche.
- DISCOVERED, currently not indexed. Google sa che la pagina esiste, in genere perché l'ha trovata nel sitemap, ma ha deciso di non crawlarla. È una decisione attiva, non una dimenticanza.
- CRAWLED, currently not indexed. Google ha visitato la pagina, l'ha letta, e ha deciso di non aggiungerla all'indice. Significa che il contenuto c'è ma non lo trova abbastanza interessante per spendere spazio indice.
Sulla mia property giovanniliguori.it la distribuzione era questa:
- 31 INDEXED
- 38 DISCOVERED, currently not indexed
- 35 UNKNOWN (stato grezzo: l'API non ha potuto leggere la pagina al momento della chiamata, situazione tipica di URL appena pubblicati o di pagine con segnali ambigui)
- 1 redirect-in-sitemap (URL spostato senza aggiornare il sitemap)
Il dato grosso non è il 29,5% INDEXED. È il fatto che 38 pagine sono DISCOVERED. Vuol dire che Google ha letto il sitemap, ha visto l'URL, e ha consapevolmente scelto di non spendere il suo crawl budget per scaricarla.
La domanda vera diventa: cosa segnala a Google che vale la pena crawlare un URL? La risposta breve è authority del sito, freschezza del sitemap, coerenza delle canonical, e link interni che puntano verso la pagina. Quattro segnali, ognuno indipendente. Bastava che uno fosse rotto per far cadere l'URL in DISCOVERED.
I quattro fix tecnici applicati in produzione
L'11 maggio è stato anche il giorno del deploy e0a24e9 su Vercel. Quattro modifiche al codice di giovanniliguori2-next, tutte landed prima di iniziare il monitoring. Le elenco con il razionale tecnico.
Fix 1: sitemap dinamico con ISR revalidate=300
Il problema. Il sitemap su Next.js 15 era stale 24 ore. Quando pubblicavo un articolo via Sanity, il nuovo URL non appariva nel sitemap fino al rebuild successivo, che spesso era il giorno dopo. Per Google, un sitemap che si aggiorna ogni 24 ore è un segnale debole sulla freschezza del sito.
Il fix. Ho aggiunto export const revalidate = 300 al route handler del sitemap, che forza Next.js a rigenerarlo ogni 5 minuti via Incremental Static Regeneration. Il sitemap adesso è praticamente in tempo reale: pubblico un post su Sanity, 5 minuti dopo l'URL è nel sitemap, e quando Google lo crawla trova un sitemap fresco.
// app/sitemap.ts
export const revalidate = 300
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const posts = await getAllPublishedPosts()
return [
{ url: 'https://giovanniliguori.it', priority: 1.0 },
...posts.map(p => ({
url: `https://giovanniliguori.it/blog/${p.slug}`,
lastModified: p.publishDate,
priority: 0.7,
})),
]
}Fix 2: canonical SSR su app/blog/[slug]
Il problema. La canonical era impostata via client-side meta tag. Google a volte legge la canonical lato server e poi non aspetta il client per confermare. Risultato: canonical signal debole, che in alcuni casi veniva sovrascritto da euristiche interne.
Il fix. Emettere la canonical direttamente nel generateMetadata SSR. Adesso ogni pagina blog ha:
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug)
return {
title: post.seo?.title || post.title,
description: post.seo?.description,
alternates: {
canonical: `https://giovanniliguori.it/blog/${params.slug}`,
},
}
}Canonical hardcoded nel response HTML iniziale. Google la trova al primo byte del documento. Zero ambiguità.
Fix 3: webhook /api/revalidate con signature check HMAC
Il problema. Anche con sitemap ISR a 5 minuti, le singole pagine blog erano servite con cache CDN che durava 30 minuti. Quando aggiornavo un articolo, la cache vecchia restava online finché non scadeva il TTL.
Il fix. Endpoint webhook su /api/revalidate che Sanity chiama dopo ogni publish. Il webhook verifica la signature HMAC SHA-256 per prevenire abuse, e invalida solo i path che sono cambiati:
// app/api/revalidate/route.ts
import { revalidatePath } from 'next/cache'
import { createHmac, timingSafeEqual } from 'crypto'
export async function POST(req: Request) {
const signature = req.headers.get('sanity-webhook-signature')
const body = await req.text()
const expected = createHmac('sha256', process.env.SANITY_WEBHOOK_SECRET!)
.update(body)
.digest('hex')
if (!timingSafeEqual(Buffer.from(signature || ''), Buffer.from(expected))) {
return new Response('invalid signature', { status: 401 })
}
const payload = JSON.parse(body)
revalidatePath(`/blog/${payload.slug.current}`)
revalidatePath('/sitemap.xml')
return Response.json({ revalidated: true })
}Sanity invia il webhook al publish, Next.js invalida la cache, l'URL nuovo è servibile in pochi secondi. Niente più 30 minuti di buco tra publish e visibilità live.
Fix 4 (rimandato): noindex su /links e /dashboard
Il problema. Due pagine interne (/links e /dashboard) appaiono nel sitemap ma non dovrebbero essere indicizzate. Sono pagine utility, non contenuto editoriale. Google le scopre, prova a indicizzarle, le scarta. Sprecano crawl budget.
Il fix. Aggiungere robots: { index: false, follow: true } nel metadata e rimuoverle dal sitemap.
Questo lo lascio per la prossima settimana. L'impatto è basso (3 URL su 105) e il deploy e0a24e9 aveva già dentro modifiche più critiche. La patch è pronta nel report gsc-cleanup-patch-2026-05-11.md e va landata insieme ai prossimi cleanup di basso impatto.
Il monitoring giornaliero che ho schedulato
Aver applicato i fix non significa niente se non misuri il delta. Per questo ho schedulato un task gsc-indexing-daily-monitor che gira ogni mattina alle 09:00 via cron.
Il task usa Haiku come modello, costa centesimi per esecuzione, e fa una cosa sola. Chiama URL Inspection API per i 105 URL del sitemap, salva il count INDEXED, DISCOVERED, UNKNOWN su un file storico, e calcola il delta rispetto al giorno precedente. Se il numero INDEXED cala invece di salire, manda un alert. Se sale di più di 5 in un giorno, log come milestone.
L'output finisce in system-signals.md sotto la sezione ## seo-indexing che il weekly-system-orchestrator legge la domenica per generare le direttive della settimana. Il discorso è che senza monitoring continuo ogni audit è una foto, non un film. E con le metriche SEO il film conta sensibilmente più della foto.
In parallelo gira una manual actions queue (reports/gsc-manual-actions-2026-05-11.md). Sitemap resubmit settimanale, 10 "Richiedi Indicizzazione" al giorno via UI GSC, 2 "Validate Fix" sui report di errori vecchi. La parte manuale resta perché Google non espone via API gli ultimi due strumenti. Sono operazioni da 5 minuti totali al giorno.
Senza il monitoring giornaliero non saprei se il deploy ha mosso davvero qualcosa o se sto guardando l'illusione di aver risolto. Con il monitoring, ogni mattina vedo il delta. Mercoledì il delta era +2 INDEXED, +1 alla volta. Il caso studio Routines, per dire, è passato da DISCOVERED a INDEXED il giorno dopo il deploy.
Cosa NON ha funzionato
Tre cose che ho provato e che hanno avuto effetto minore o nullo.
- Resubmit massivo del sitemap. Andare nel Search Console e cliccare "invia di nuovo" sul sitemap ogni giorno non ha cambiato il rate di indicizzazione. Google legge il sitemap quando vuole. Il bottone "invia" è più un placebo per chi lo gestisce che un trigger reale per il crawler.
- Aspettare. Per due settimane ho lasciato fare. Risultato: zero URL nuovi indicizzati. La pazienza con Google funziona se hai authority alta. Sotto una certa soglia, devi spingere con segnali strutturali, non aspettare.
- Ottimizzare il contenuto delle pagine DISCOVERED. Riscrivere il titolo o l'intro di un post che Google ha già visto e scartato non sblocca l'indicizzazione. Google ha già preso una decisione su quell'URL. Per cambiarla servono nuovi segnali strutturali (link in arrivo, freschezza del sitemap, modifiche al body sostanziose), non micro-ottimizzazioni SEO sui meta tag.
La lezione è netta. 30% del tempo SEO va su contenuto, 70% va su infrastruttura. La maggior parte dei blog inverte la proporzione e fa solo SEO copy. Il risultato è quello che vediamo nei miei dati: pagine ben scritte che restano invisibili a Google.
Quando preoccuparsi davvero (e quando no)
Una domanda onesta: il 70% di pagine non indicizzate è un disastro o è normale? La risposta è che dipende dalla composizione del sitemap.
Se le pagine non indicizzate sono URL di sistema (tag pagination, archivi mensili, pagine utility), il 70% non indicizzato è perfettamente sano. Google sta facendo il suo lavoro: ignora ciò che non serve agli utenti finali e risparmia crawl budget per il contenuto vero.
Se le pagine non indicizzate sono articoli editoriali con contenuto reale e link interni in arrivo, allora 70% è un problema. Significa che il sito non ha abbastanza authority per convincere Google a spendere crawl budget su tutto il catalogo.
Nel mio caso, le 38 pagine DISCOVERED includevano alcuni articoli che sapevo dovevano essere indicizzati. Per esempio il caso studio sull'architettura ibrida Cowork locale + Routines cloud stava in DISCOVERED dal giorno della pubblicazione e nei giorni successivi al deploy e0a24e9 è passato a INDEXED. Stesso pattern per articoli sul cluster automation. Senza i quattro fix tecnici, sospetto che ci sarebbero rimasti per settimane.
Per chi sta pensando di replicare l'audit sul proprio sito, il setup minimo è semplice.
- Un service account Google Cloud con scope Search Console abilitato
- Uno script Python che chiama
urlInspection.index.inspectper ogni URL del sitemap (rate limit 600 richieste al minuto, in pratica più che sufficiente per siti sotto i 5.000 URL) - Un parser dei tre stati (INDEXED, DISCOVERED, UNKNOWN) che salva il risultato in CSV o JSON
- Una cron che lo fa girare ogni giorno o ogni settimana
Tutto il resto è interpretazione. Per il framework completo dell'audit, la documentazione ufficiale Google sui sitemap è il punto di partenza. Per vedere come questo tipo di task si inserisce in un sistema più ampio di automazione AI in produzione per B2B, il caso studio sulla guida Claude per freelancer e PMI racconta come componenti come gsc-indexing-daily-monitor si combinano in un orchestrator settimanale che decide priorità e budget di lavoro.
La lezione operativa
Per otto mesi ho creduto che SEO fosse copy. Era 30% copy e 70% infrastruttura. La mia property era invisibile a Google per metà non perché scrivessi male, ma perché i segnali tecnici erano stale, ambigui, o dispersi.
Adesso il target è 80% INDEXED entro fine giugno. Il gap da chiudere è 50 punti percentuali in sette settimane. Il piano sta in pochi punti: monitoring giornaliero attivo, manual indexing queue 10 URL al giorno, due settimane di osservazione del nuovo equilibrio post-fix, poi decisione se mettere in coda i restanti cleanup di basso impatto.
Chi monitora i tre stati di indicizzazione settimanalmente ha un vantaggio enorme su chi guarda solo il count totale di GSC. Non è una questione di volume, è una questione di dove si fissa la metrica. Il count totale ti dice "stai pubblicando". I tre stati ti dicono "Google ti sta credendo".
Se hai un blog tecnico e il rate di indicizzazione ti sembra basso, il primo passo non è scrivere di più. È misurare quanti URL stanno effettivamente nel filtro di Google. Quasi sempre il numero sorprende verso il basso. Quando lo vedi nero su bianco la conversazione interna cambia. Smetti di chiederti "come scrivo titoli migliori" e cominci a chiederti "perché la sitemap non viene creduta". Sono due piani di lavoro diversi, e quello tecnico è quasi sempre il collo di bottiglia reale.
Il prossimo audit è programmato per il 25 maggio. Due settimane di dati post-deploy, abbastanza per misurare se il rate INDEXED sale almeno di 10 punti percentuali. Se sale, il piano regge. Se non sale, vuol dire che il problema non era la freschezza dei segnali ma l'authority del dominio, e a quel punto il lavoro si sposta sul link building e sulla profondità di topic cluster. Diversa medicina, diversa cadenza.
E niente, da qui in poi misuro tutto.
— Newsletter LinkedIn
Ogni settimana condivido workflow, errori e numeri reali
21 automazioni in produzione, zero dipendenti. Su LinkedIn documento il dietro le quinte: cosa funziona, cosa no, e i dati che nessuno mostra.
