SEO tecnica con Next.js: metadata, sitemap, hreflang e JSON-LD con l'App Router
Quasi tutto si imposta nel codice, una volta sola. Il resto è non nascondere il testo dietro il JavaScript.

Next.js è adatto alla SEO?
Sì, perché può generare pagine statiche o renderizzate dal server con tutto il testo già nell'HTML, ed è questo che conta per i motori. Non è però un vantaggio automatico: un'app Next.js piena di componenti client che caricano i contenuti dopo l'avvio può essere invisibile quanto una single-page app.
Google elabora le pagine JavaScript in tre fasi, scansione, rendering e indicizzazione, e le mette in una coda di rendering dove possono restare pochi secondi o più a lungo. La stessa documentazione ricorda che non tutti i bot eseguono JavaScript: il rendering lato server o il pre-rendering restano la scelta più sicura, anche per i crawler dei motori di risposta.
Come si gestiscono title, description e canonical?
Con la Metadata API dell'App Router: un oggetto metadata statico, o una funzione generateMetadata quando i dati dipendono dalla pagina, esportati da ogni layout o pagina. Next.js li trasforma nei tag dell'head. Imposta metadataBase nel layout radice con il dominio di produzione: da lì i campi che richiedono URL assoluti, come canonical e Open Graph, accettano percorsi relativi.
- title e description unici per pagina, scritti per chi legge: sono ciò che compare nei risultati.
- alternates.canonical su ogni pagina, che punta a sé stessa nella sua lingua.
- alternates.languages con tutte le versioni linguistiche, più x-default.
- openGraph con un'immagine dedicata, per come la pagina appare quando viene condivisa.
Una novità da conoscere: da Next.js 15.2 i metadata di generateMetadata possono arrivare in streaming, aggiunti al body dopo il primo invio della pagina. La documentazione di generateMetadata spiega che Next.js riconosce dallo user agent i bot che non eseguono JavaScript e per loro mette i tag nell'head, e che Googlebot interpreta correttamente anche i tag nel body. In ogni caso apri il sorgente HTML di una pagina in produzione e controlla dove sono title e canonical.
Come si impostano hreflang e versioni linguistiche?
Si impostano con alternates.languages nei metadata di ogni pagina oppure nella sitemap, rispettando le regole di Google: ogni versione deve elencare sé stessa e tutte le altre, altrimenti i tag vengono ignorati. Google considera equivalenti tre metodi (tag nell'head, intestazioni HTTP, sitemap): scegline uno e tienilo coerente.
Due dettagli si sbagliano spesso. x-default indica la versione da mostrare quando nessuna lingua corrisponde a quella del browser. E Google non usa hreflang né l'attributo lang per capire in che lingua è una pagina: lo deduce dal contenuto. Una pagina inglese piena di frasi rimaste in italiano confonde più di un tag mancante.
Su questo sito l'italiano vive alla radice e l'inglese sotto /en, con due layout radice separati, così ogni pagina dichiara la propria lingua nell'attributo lang. Nella sitemap ogni URL porta le sue alternative it, en e x-default, che punta alla versione italiana.
Come si generano sitemap e robots.txt?
Con due file nella cartella app: sitemap.ts restituisce l'elenco degli URL e Next.js lo serve come XML; robots.ts fa lo stesso per il robots.txt, che può anche restare un file statico in public, come su questo sito. Secondo la documentazione sulla sitemap di Next.js, è una route speciale messa in cache per default, salvo che usi API dinamiche.
Ogni voce della sitemap può avere le sue alternative linguistiche e la data di ultima modifica. Su questa Google è chiaro: usa lastmod solo se è accurata in modo costante e verificabile, e ignora priority e changefreq. Mettere la data della build su tutte le pagine è il modo più rapido per farla ignorare. Una sitemap ha un limite di 50.000 URL o 50 MB non compressi; oltre si divide, in Next.js con generateSitemaps.
| Elemento | Dove in Next.js | Regola di Google da rispettare |
|---|---|---|
| Title e description | metadata o generateMetadata in page e layout | Unici per pagina, scritti per chi legge |
| Canonical | alternates.canonical, con metadataBase nel layout radice | Un solo URL di riferimento per ogni contenuto |
| Hreflang | alternates.languages nei metadata o nella sitemap | Reciproci, ogni versione elenca sé stessa e le altre, più x-default |
| Sitemap | app/sitemap.ts; generateSitemaps oltre 50.000 URL | lastmod solo se vero; priority e changefreq ignorati |
| Robots | app/robots.ts o public/robots.txt | Non bloccare le pagine che vuoi togliere con noindex |
| Dati strutturati | Tag script application/ld+json in page o layout | Devono corrispondere al testo visibile |
| Redirect | redirects in next.config, con permanent per i definitivi | 308 e 301 sono entrambi redirect permanenti |
Come si aggiunge il JSON-LD in Next.js?
Si aggiunge come tag script di tipo application/ld+json dentro la pagina o il layout, come raccomanda la guida JSON-LD di Next.js. L'oggetto si serializza con JSON.stringify, sostituendo il carattere < con il suo codice unicode per evitare iniezioni di HTML; la stessa guida suggerisce il Rich Results Test e lo Schema Markup Validator per controllarlo.
Cosa metterci: Organization nella home, Article o BlogPosting negli articoli con autore e date vere, BreadcrumbList nelle pagine interne. Su questo sito ogni pagina ha un unico grafo JSON-LD che collega organizzazione, sito e pagina, e l'organizzazione dichiara i tre brand del gruppo come sotto-organizzazioni. Lo schema deve dire le stesse cose del testo visibile: è igiene, non una scorciatoia per le risposte AI, come spieghiamo nell'articolo su come farsi citare da ChatGPT e dalle AI Overviews.
Quanto contano velocità e Core Web Vitals?
Contano come parte dell'esperienza della pagina: Google raccomanda di ottenere buoni Core Web Vitals e li descrive come allineati a ciò che i suoi sistemi di ranking vogliono premiare. Non salvano un contenuto debole, ma sono la parte della SEO che dipende quasi solo da come scrivi il codice.
2,5 s
- next/image con dimensioni note: Next.js le usa per riservare lo spazio dell'immagine ed evitare spostamenti del layout.
- next/font per ospitare i font sul proprio dominio e caricarli senza salti di layout.
- Componenti server per default: i componenti client solo dove serve interazione, così il JavaScript inviato resta poco.
- Caricamento differito delle parti pesanti, come 3D, mappe e video, con import dinamico: è ciò che facciamo con le scene three.js di questo sito.
Checklist prima di andare online (nostra)
metadataBase e canonical
Dominio di produzione nel layout radice, canonical su ogni pagina, nessun URL di staging nei tag.
Hreflang reciproci
Ogni versione elenca sé stessa e le altre, più x-default; controlla due o tre pagine nel sorgente HTML.
Sitemap con date vere
lastmod legata all'ultima modifica reale del contenuto, non alla build. Invia la sitemap a Search Console e Bing Webmaster Tools.
Robots e noindex dell'ambiente di prova
Il blocco totale o il noindex usati in staging non devono arrivare in produzione: è un errore classico dei lanci.
Redirect dai vecchi URL
Con permanent: true Next.js risponde con un 308, che Google tratta come permanente al pari del 301 secondo la sua documentazione sui redirect.
Controllo URL in Search Console
Verifica l'HTML renderizzato di una pagina per tipo: home, servizio, articolo. Se il testo non c'è lì, non c'è per Google.
Se il sito è il primo passo di un prodotto, le scelte tecniche vanno fatte prima dei contenuti: lo spieghiamo nella guida alla SEO per startup. Per un software in abbonamento, la guida alla SEO per SaaS aggiunge come separare sito pubblico e app.
Domande frequenti
App Router o Pages Router per la SEO?
Entrambi possono produrre HTML lato server. L'App Router ha la Metadata API e le convenzioni per sitemap e robots già integrate, quindi per un progetto nuovo è la strada più diretta.
Serve una libreria come next-seo?
Con l'App Router di solito no: la Metadata API copre title, description, canonical, hreflang e Open Graph. Una libreria esterna aggiunge una dipendenza da mantenere senza dare molto in più.
Come genero in build le pagine del blog?
Con generateStaticParams nelle route dinamiche: Next.js genera in build una pagina per ogni parametro restituito, invece di generarla a ogni richiesta. È il modo più semplice per avere articoli statici con tutto il testo nell'HTML.
Come verifico cosa vede Google?
Con il Controllo URL di Search Console, che mostra l'HTML renderizzato e le risorse che Google non è riuscito a caricare. Per i dati strutturati usa il Rich Results Test o lo Schema Markup Validator.
Le scene 3D o le animazioni penalizzano la SEO?
Non di per sé. Il rischio è mettere testi importanti dentro un canvas o caricare tutto subito, peggiorando i tempi di caricamento. Tieni i contenuti nell'HTML e carica il 3D dopo, solo quando serve.
Fonti
- Next.js Docs, generateMetadata (incl. streaming metadata) (19 ottobre 2026)
- Next.js Docs, sitemap.xml file convention (19 ottobre 2026)
- Next.js Docs, How to implement JSON-LD in your Next.js application (19 ottobre 2026)
- Google Search Central, Understand JavaScript SEO basics (aggiornata 2026-03-04) (19 ottobre 2026)
- Google Search Central, Tell Google about localized versions of your page (aggiornata 2026-09-21) (19 ottobre 2026)
- Google Search Central, Build and submit a sitemap (aggiornata 2026-07-08) (19 ottobre 2026)
- Google Search Central, Understanding Core Web Vitals and Google search results (aggiornata 2025-12-10) (19 ottobre 2026)
- Google Search Central, Redirects and Google Search (aggiornata 2026-04-14) (19 ottobre 2026)
Dati e definizioni verificati alle date indicate.




