Salta al contenuto
Neaptidestudio
blog

Checklist SEO per Next.js App Router: visibilità SSR, canonical, hreflang e crawler IA

Neaptide · 30 ottobre 2026 · 8 min di lettura

Verifica ciò che Next.js App Router restituisce davvero nell’HTML iniziale: titoli SSR visibili senza opacity:0, ereditarietà di alternates, link lingua e redirect.

In questo articolo
Checklist SEO per Next.js App Router — 1 SSR HTML (<h1> visibile) · 2 Alternates (6 hreflang + RSS) · 3 Link HTML (<a hreflang>) · 4 Schema (JSON-LD + sitemap).

Un sito realizzato con Next.js App Router può apparire perfetto nel browser ma servire il titolo <h1> nascosto da style="opacity:0" nell’HTML iniziale, sovrascrivere i tag <link rel="alternate"> del layout padre o chiudere il selettore lingua dentro pulsanti <button> privi di href. Prima del rilascio è essenziale ispezionare la risposta HTTP grezza e l’HTML renderizzato dal server.

Anche con i Server Components, i wrapper di animazione client, generateMetadata() e middleware.ts determinano ciò che ricevono Googlebot e i crawler di ricerca IA (GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot). Di seguito presentiamo cinque problemi tecnici reali individuati e risolti sul sito multilingue Next.js 15 di Neaptide e una checklist ripetibile.

Cosa ha rilevato e corretto l’audit sul nostro sito Next.js 15?

Nell’ottobre 2026 abbiamo verificato l’HTML servito, gli header HTTP, i metadati e la sitemap nelle sei lingue di Neaptide. La tabella riassume le cinque anomalie tecniche riscontrate e il risultato verificato in produzione.

Cinque controlli SEO Next.js App Router dall’audit di produzione di Neaptide
Livello ispezionatoDifetto nell’HTML SSR inizialeCorrezione applicata e risultato verificato
Wrapper di animazione Reveal.tsx e Hero.tsxIl titolo <h1>, l’introduzione e le schede uscivano con style="opacity:0;transform:translateY(12px)" fino all’idratazione (~1,2 s)Rimosso opacity:0 dallo stato SSR iniziale; titoli e testi sono subito visibili nell’HTML grezzo
Helper generateMetadata() in lib/meta.tsL’oggetto alternates: { canonical, languages } delle pagine sovrascriveva il layout rimuovendo <link rel="alternate" type="application/rss+xml">Aggiunto types: { "application/rss+xml": "https://www.neaptide.ai/feed.xml" } in pageMetadata()
Selettore lingua components/LangSwitcher.tsxLe opzioni lingua venivano montate solo al clic come elementi <button> senza attributo hrefTutte le 6 lingue sono renderizzate nel DOM SSR come link <a href={...} hrefLang={l} lang={l}>
Redirect della radice (/) in middleware.tsI bot che richiedevano / senza header geo o Accept-Language non ricevevano un header Vary completoRedirect deterministico a x-default (/en) con Vary: Accept-Language, Cookie, x-vercel-ip-country, cf-ipcountry
Dati strutturati lib/schema.ts e app/sitemap.tsTre pagine di servizio impostavano areaServed: United States; la sitemap ometteva le immagini dei casi studioAllineato areaServed e aggiunte copertine e grafici localizzati in sitemap.xml

Queste osservazioni riguardano modifiche tecniche verificate sul nostro codice. Risolverle elimina ostacoli di rendering e scansione; il posizionamento organico e le citazioni nelle risposte IA dipendono comunque dalla concorrenza e dall’autorevolezza complessiva del sito.

Perché style="opacity:0" nelle animazioni penalizza LCP e crawler?

Molti siti Next.js racchiudono titoli e sezioni principali in componenti di animazione o Framer Motion con stato iniziale opacity: 0. Poiché Next.js pre-renderizza anche i Client Components sul server usando lo stato iniziale, l’HTML arriva con style="opacity:0" sul tag <h1> e sul testo sopra la piega.

Questo ritarda il Largest Contentful Paint (LCP) fino al completamento dell’idratazione JavaScript e presenta i titoli principali come nascosti ai crawler che leggono l’HTML grezzo. Mantieni il testo visibile nell’HTML SSR usando solo una leggera traslazione (transform: translateY(12px)) senza opacity: 0.

Come generateMetadata può cancellare i tag alternates del layout?

In Next.js App Router l’unione dei metadati tra layout e pagina è superficiale. Se una pagina restituisce un proprio oggetto alternates con canonical e languages, sostituisce interamente l’oggetto alternates del layout genitore.

Centralizza canonical, languages (incluso x-default) e types (come il feed RSS) in un’unica funzione condivisa:

export function pageMetadata(locale: Locale, opts: PageMetaInput): Metadata {
  const canonicalUrl = `${SITE.url}${localeHref(locale, opts.path)}`;
  const languages: Record<string, string> = {};
  for (const l of LOCALES) {
    languages[l] = `${SITE.url}${localeHref(l, opts.path)}`;
  }
  languages["x-default"] = `${SITE.url}${localeHref(X_DEFAULT_LOCALE, opts.path)}`;

  return {
    alternates: {
      canonical: canonicalUrl,
      languages,
      types: {
        "application/rss+xml": `${SITE.url}/feed.xml`,
      },
    },
  };
}

Perché selettore lingua e redirect della radice devono essere espliciti per i bot?

Un selettore lingua che monta le opzioni solo al clic o usa pulsanti <button> non offre link HTML scansionabili tra le lingue. Renderizzare veri link <a href="/en/..." hrefLang="en" lang="en"> nel DOM dell’header permette ai crawler di scoprire direttamente tutte le varianti linguistiche.

Verifica inoltre il comportamento della radice / quando un bot effettua una richiesta senza cookie né header Accept-Language: il middleware deve reindirizzare in modo deterministico alla lingua x-default (/en) inviando l’header Vary appropriato.

Come verificare un rilascio Next.js App Router in sei passaggi

Esegui questi sei controlli prima di approvare il rilascio:

  1. Visibilità SSR grezza: scarica la pagina con curl -s e verifica che l’unico <h1> e il testo principale compaiano senza style="opacity:0".
  2. Parità di canonical e hreflang: controlla che ogni URL localizzato esponga il canonical autoreferenziale, le 6 lingue, x-default e il link RSS.
  3. Link HTML scansionabili: conferma che menu, footer e selettore lingua usino tag <a href="..."> nell’HTML iniziale.
  4. Redirect della radice: testa / con curl -I e un header Accept-Language vuoto per confermare un singolo redirect permanente verso la destinazione prevista.
  5. Coerenza JSON-LD: verifica che WebPage, Service, Article, BreadcrumbList e FAQPage corrispondano al testo visibile e alla lingua della pagina.
  6. Copertura sitemap.xml e llms.txt: controlla che tutte le rotte e le immagini principali siano presenti in /sitemap.xml e /llms.txt.
curl -s https://www.neaptide.ai/en | grep -E '<h1|rel="canonical"|hrefLang|application/rss\+xml'
curl -I -H 'Accept-Language:' https://www.neaptide.ai/

Se desideri una verifica tecnica del tuo sito Next.js, Neaptide esegue audit SEO e GEO con controlli HTTP riproducibili e ticket pronti per gli sviluppatori.

faq

L'essenziale in breve

Usare i Server Components di Next.js garantisce automaticamente una buona SEO tecnica?

No. I wrapper di animazione client con opacity:0, gli oggetti generateMetadata() incompleti, i menu con <button> e i redirect nel middleware possono comunque nascondere il contenuto o interrompere i segnali canonical e hreflang.

Perché style="opacity:0" nell’HTML SSR è un problema se JavaScript mostra comunque il testo?

Ritarda il Largest Contentful Paint (LCP) fino al termine dell’idratazione e segnala i titoli come invisibili ai crawler che analizzano l’HTML grezzo senza eseguire JavaScript.

Perché il link RSS del layout scompare nelle pagine interne?

Perché Next.js unisce i metadati in modo superficiale: quando una pagina definisce alternates, sostituisce l’intero oggetto alternates del layout padre se alternates.types non è incluso nell’helper condiviso.

Servono i link <a hreflang> nel selettore lingua se hreflang è già in <head>?

Sì. I link <a href="..." hrefLang="..."> nel DOM consentono ai crawler di passare direttamente da una versione linguistica all’altra su ogni pagina.

Cosa deve restituire la radice / a un crawler privo di header di lingua?

Un redirect deterministico verso la lingua x-default (ad esempio /en) accompagnato dall’header Vary con Accept-Language, Cookie e gli header geografici.

Cosa include l’audit SEO per Next.js di Neaptide?

Analizziamo HTML SSR, LCP, matrice canonical e hreflang, dati strutturati JSON-LD, sitemap e accesso dei bot IA, consegnando ticket tecnici con riferimenti ai file del progetto.