seojuice

La SEO delle SPA è un problema di delivery, non di rendering

Vadim Kravcenko
Vadim Kravcenko
· Updated · 13 min read

TL;DR: La SEO per SPA non è più un problema di rendering, ma di delivery: URL, codici di stato, metadati e contenuto principale devono esistere prima che JavaScript entri in gioco, perché Google potrebbe renderizzare in ritardo e i crawler basati su AI spesso non renderizzano affatto.

La SEO per SPA non riguarda più se Google «supporta JavaScript»

La maggior parte dei consigli sull’SEO per SPA parte ancora dalla domanda sbagliata: Google riesce a renderizzare JavaScript?

Sì. Google sa renderizzare JavaScript. Martin Splitt lo ripete da anni, eppure molti continuano a fare debug delle SPA guardando view-source: come se fosse la pagina che Google ha indicizzato.

«Molte persone continuano a guardare il sorgente. Non è quello che usiamo per l’indicizzazione. Noi usiamo l’HTML renderizzato.»

Martin Splitt, Developer Advocate @ Google

Questa citazione conta perché smonta una cattiva abitudine. Se controlli solo il sorgente iniziale di un’app React, Vue, Angular, SvelteKit, Nuxt, Remix o Next.js, rischi di perdere ciò che Google vede davvero. Il DOM renderizzato fa la differenza.

Ma questo non significa che il rendering lato client sia sicuro per ogni route pubblica. Renderizzare costa tempo, può fallire e può avvenire dopo la scansione. Altri bot potrebbero non renderizzare mai. La vera domanda per lo spa seo è se il crawler riceve un documento significativo abbastanza presto.

“View source” è l’abitudine di debug sbagliata

“View source” mostra la prima risposta HTML. In una classica app CSR, quella risposta può essere un guscio vuoto, un nodo radice, un bundle di script e una preghiera. Google potrebbe renderizzare la pagina più tardi, eseguire la route, chiamare le API e scoprire il contenuto reale. Forse.

Quel «forse» è dove i ranking diventano strani. La pagina può sembrare perfetta nel tuo browser e risultare fragile per la ricerca: il browser è paziente, i crawler sono sistemi con code, budget, timeout e modalità di errore.

Il DOM renderizzato conta, ma l’HTML al primo byte vince ancora

seojuice.io è diviso di proposito: le pagine pubbliche consegnano HTML statico first, la dashboard dopo il login si comporta da app. Due strategie di rendering sotto un solo dominio, perché quelle route hanno compiti diversi.

Blog, strumenti e landing page devono essere trovati, scansionati, compresi, condivisi e citati. La dashboard non deve posizionarsi per “interfaccia valutazione salute pagina” e mai lo farà. JavaScript può migliorare la pagina pubblica dopo il caricamento, ma la prima risposta deve già sembrare una pagina.

I crawler AI hanno cambiato il profilo di rischio

Per anni ho trattato il problema come se riguardasse solo Google (mi sbagliavo). Poi i crawler AI hanno reso il vecchio shortcut ancora peggiore.

«I risultati mostrano con coerenza che nessuno dei principali crawler AI attualmente renderizza JavaScript.»

Vercel Engineering

Se GPTBot, ClaudeBot, PerplexityBot o un altro crawler vede solo un app shell, per quella superficie il tuo contenuto è come se non esistesse. Il supporto al rendering di Google aiuta Google (e solo Google): non salva ogni crawler, bot di anteprima, strumento di monitoraggio, parser social o sistema di ingestione AI.

Timeline che confronta come Googlebot, crawler senza JavaScript e crawler AI vedono il contenuto di una SPA
FONTE: Riferimento SPA-SEO di SEOJuice, basato sulla documentazione di rendering di Google e sulle misurazioni 2024 di Vercel sull’esecuzione JavaScript dei crawler AI.

Decidi quali route della SPA sono pagine e quali sono stati dell’app

È lo step che la maggior parte dei team salta. Chiedono se l’intera SPA abbia bisogno di SSR. Quel frame spreca tempo di engineering.

Una vera SPA mescola quasi sempre due cose: pagine indicizzabili e stati dell’app privati. Pagine prezzi, post del blog, documentazione, template, integrazioni, pagine di confronto e landing di prodotto sono pagine. Dashboard, step di onboarding, modali, filtri, schermate account e report salvati sono stati dell’app.

La correzione parte dalla classificazione. Non chiedere agli sviluppatori di «sistemare la SEO dell’app». Chiedi di segnare quali route meritano traffico di ricerca, poi scegli rendering, indicizzazione, canonical e codici di stato per ciascuna route.

Tipo di route Dovrebbe posizionarsi? Scelta di rendering Regola di indicizzazione
Post del blog SSG o SSR Index, canonical self
Landing di prodotto SSG o SSR Index, canonical self
Pagina di risultati di ricerca Di solito no CSR o SSR Spesso noindex
Route dashboard No CSR va bene Bloccata dietro auth o noindex
URL con filtro facet A volte SSR solo se curato Canonical o noindex
Albero decisionale per scegliere il trattamento SEO e il modello di rendering per le route di una SPA
FONTE: Framework di classificazione route SPA-SEO di SEOJuice.

Così lo spiego in un audit SEO tecnico. Una SPA con 40 URL pubblici e 4 000 stati di dashboard non ha 4 040 pagine SEO. Ha 40 pagine e un’interfaccia di prodotto.

Questa distinzione cambia la roadmap. Le route pubbliche hanno bisogno di URL stabili, canonical self, metadati consegnati dal server, link crawlable, HTML utile al primo byte e codici di stato corretti. Le route di dashboard richiedono interazione veloce, auth, gestione stato e privacy. Forzare entrambi i gruppi in un solo modello di rendering di solito peggiora entrambi.

Da mindnow era l’errore SPA più comune che vedevo nei progetti cliente. Il team voleva un’unica architettura frontend elegante. La search voleva documenti noiosi. Il compromesso non era abbandonare l’app, ma smettere di fingere che ogni route avesse lo stesso scopo.

Scegli il modello di rendering giusto prima di scrivere ticket SEO

La strategia di rendering è una scelta architetturale, non un flag in un plugin SEO: se scegli il modello sbagliato, ogni ticket successivo diventa una patch.

Tabella comparativa dei modelli di rendering per SPA ai fini SEO
FONTE: Riferimento strategie di rendering SEOJuice, basato sulla documentazione di Google e sulla guida Next.js di Vercel.

CSR: ok per dashboard, rischioso per landing page

Il rendering lato client va benissimo per schermate software autenticate. Se l’utente deve fare login, i crawler non dovrebbero indicizzare la route comunque. Il CSR diventa rischioso quando lo stesso shell serve pagine prezzi, documenti, articoli e pagine prodotto dove il contenuto appare solo dopo che JavaScript gira e le API rispondono.

SSG: noioso, veloce e di solito la risposta giusta

La generazione statica crea le pagine in HTML prima del tempo (di solito in fase di build o deploy). Per blog, documentazione, changelog, pagine glossario, template e gran parte del marketing, l’SSG è imbattibile: veloce, cache-able, economico e amico dei crawler.

SSR: utile quando il contenuto pubblico cambia spesso

Il rendering lato server è più adatto quando il contenuto pubblico varia per richiesta, geografia, inventario, permessi o freschezza. Lee Robinson ha descritto il modello Next.js in modo semplice:

«Next.js pre-renderizza la pagina in HTML sul server a ogni richiesta.»

Lee Robinson, VP Developer Experience @ Vercel

L’SSR dà ai crawler HTML senza aspettare il bundle client, pur riflettendo dati freschi.

ISR: il compromesso pratico per i siti grandi

L’Incremental Static Regeneration (pagine statiche aggiornate dopo la pubblicazione) è spesso il miglior compromesso per grandi library di contenuti. Ottieni HTML statico per la maggior parte delle richieste e rigenerazione quando il contenuto cambia. Per SEO programmatico, docs e grandi librerie di template, l’ISR evita rebuild infiniti senza tornare al CSR completo.

Rendering dinamico: il workaround destinato a scadere

Il rendering dinamico serve una versione ai crawler e un’altra agli utenti. Può salvare una SPA legacy quando la migrazione non è pronta — ma non disegnerei una nuova strategia search basandomi su di esso.

«Lo vedrei come un workaround temporaneo – dove temporaneo può voler dire un paio d’anni – ma resta una soluzione a tempo.»

John Mueller, Search Advocate @ Google

È il modello mentale giusto. Usa il rendering dinamico quando serve un ponte, poi sostituisci il ponte con route pubbliche server-rendered o static-first.

Correggi le trappole di crawl delle SPA che ancora rompono l’indicizzazione

I veri fallimenti SPA SEO sono di solito noiosi. Non sono misteriose penalizzazioni di ranking, ma bug di delivery.

La prima trappola è lo shell universale. Ogni URL restituisce la stessa risposta 200, lo stesso nodo vuoto e lo stesso bundle. Il router decide dopo se /pricing, /docs/api o /totally-fake-url esistano. Costringe i crawler a lavorare troppo e crea la seconda trappola: i soft 404.

«Invece di restituire 404, risponde con 200 … mostrando sempre una pagina basata sull’esecuzione JavaScript.»

Martin Splitt, Developer Advocate @ Google

Le route non valide dovrebbero restituire veri 404 o 410. Un carino componente “page not found” lato client servito con 200 è comunque un cattivo segnale (è la trappola soft 404 che divora il budget di indicizzazione).

Diagramma che mostra la differenza tra risposte soft 404 di una SPA e veri codici di stato 404
FONTE: Riferimento trappole di crawl SPA-SEO di SEOJuice, basato sulla documentazione di Google sui soft 404 e sui consigli pubblici di Martin Splitt.

La terza trappola è la navigazione che i crawler non possono seguire. Bottoni, click handler, componenti custom e eventi del router vanno bene per l’interazione, ma la scoperta interna ha ancora bisogno di anchor crawlable con veri attributi href. Se le tue pagine più importanti sono raggiungibili solo dopo un click JavaScript, la crawlabilità è più debole di quanto sembri.

I metadati sono un altro punto critico. Molte SPA aggiornano titoli, descrizioni, canonical, tag robots, Open Graph e schema dopo i cambi di route. In un browser funziona visivamente, ma può fallire per crawler, parser social e bot AI. I metadati specifici di route devono essere presenti nell’HTML restituito per ogni URL indicizzabile.

I canonical meritano un avviso a parte. Ho visto app idratate sovrascrivere un canonical corretto con un dominio di staging, un URL root o la route precedente. Questi bug sono silenziosi. Nessuno se ne accorge finché gli URL duplicati non si raggruppano male o inizia a posizionarsi la pagina sbagliata.

L’infinite scroll è un’altra trappola quando nasconde contenuto dietro stato client. Se pagina due, tre e gli item più vecchi non hanno URL crawlable, i motori di ricerca potrebbero non scoprirli mai. Usa URL paginati di fallback per archivi e categorie importanti.

Contenuto principale caricato via API è fragile. Se H1, corpo, dettagli prodotto, recensioni o link interni richiedono due chiamate API dopo l’hydration, hai più punti di fallimento. Il traffico bot può colpire rate-limit. Le API possono bloccare user-agent sconosciuti. Timeout possono lasciare il DOM renderizzato scarno.

Il routing con hash dovrebbe restare fuori dalle pagine pubbliche indicizzabili. Un URL tipo /docs#pricing va bene per i frammenti, ma l’hash-routing per pagine reali complica discovery, canonical e analytics.

Infine, occhio ad auth e peso del bundle insieme. Contenuto pubblico avvolto per errore da check login può sparire dai crawler. Bundle pesanti possono ritardare il rendering e sprecare budget. Entrambi i problemi sembrano “JavaScript SEO”, ma la soluzione pratica è confini di route più puliti e meno lavoro client per le pagine pubbliche.

Costruisci ogni route indicizzabile prima come documento e poi come app

La miglior regola SPA SEO che conosca è semplice: se la route merita traffico di ricerca, la prima risposta deve sembrare una pagina.

Ciò significa che ogni URL pubblico deve restituire HTML utile con i segnali core già presenti:

  • Tag <title> corretto;
  • Meta description;
  • Canonical autoreferenziale;
  • Un H1 chiaro;
  • Contenuto principale;
  • Link interni crawlable;
  • Dati strutturati dove rilevanti;
  • Codice di stato corretto;
  • Tag Open Graph e Twitter se la condivisione conta.
Struttura di pagina SPA HTML-first con hydration JavaScript aggiunta dopo gli elementi SEO core
FONTE: Playbook architetturale SPA-SEO di SEOJuice per route pubbliche HTML-first.

Poi JavaScript può idratare componenti, personalizzare elementi, caricare calcolatori, tracciare eventi, filtrare tabelle e arricchire l’esperienza. Non dovrebbe essere necessario perché il crawler capisca di cosa parla la pagina.

Qui si incontrano architettura del sito e SPA SEO. Una route pubblica senza link crawlable che puntino a essa è comunque debole, anche se è server-rendered. Un documento perfettamente renderizzato ma sepolto a cinque click dietro navigazione client-only non performa come una pagina collegata da una rete interna chiara.

La regola document-first mantiene onesti i team. Pricing è un documento. Un post del blog è un documento. Una pagina docs è un documento. Un filtro dashboard salvato, un modal aperto o uno step di onboarding sono stati dell’app. Trattare lo stato dell’app come pagina search crea bloat d’indice. Trattare le pagine pubbliche come stato dell’app crea invisibilità.

Su seojuice.io questa divisione è intenzionale. Le route pubbliche devono essere abbastanza noiose per i crawler. Il prodotto può restare interattivo dopo il login. Le due idee possono convivere.

Testa la SEO della SPA con l’HTML renderizzato, non con la speranza

Se testi solo l’esperienza browser, stai testando il percorso più felice. La SEO per SPA ha bisogno di test più scomodi.

  1. Recupera l’URL con JavaScript disabilitato e verifica che il contenuto abbia ancora senso.
  2. Ispeziona l’URL in Google Search Console e rivedi l’HTML renderizzato.
  3. Confronta l’HTML iniziale con il DOM renderizzato in Chrome DevTools.
  4. Testa i codici di stato con curl -I https://example.com/missing-route.
  5. Crawla il sito con un crawler JS-capable e uno senza JS.
  6. Conferma che titoli, canonical, tag robots, schema e link interni esistano prima dell’hydration.
  7. Controlla i log server per hit bot, API bloccate, timeout e redirect inattesi.
  8. Valida i dati strutturati con il Rich Results Test di Google dopo il rendering.

Il test scomodo è quello dell’H1. Se Googlebot ha bisogno di cinque step e due chiamate API per trovare l’H1, la pagina è fragile anche se alla fine viene indicizzata.

Screaming Frog, Sitebulb, Google Search Console, Chrome DevTools, Rich Results Test e log server aiutano tutti. Lo strumento specifico conta meno del confronto: vuoi sapere cosa esiste alla prima risposta, cosa appare dopo il rendering e cosa Google ha effettivamente indicizzato.

Qui molti audit JavaScript SEO si fermano troppo presto: dimostrano che Google può renderizzare una pagina. Bene. Ora testa route non valide, paginazione, cambi canonical, cambi metadata, fail API, risposte lente e crawler non-Google.

Checklist best practice SPA SEO

Usa questa checklist a livello di route. Un “pass” globale nasconde troppi fallimenti SPA.

  • Rendering: Le pagine pubbliche usano SSG, SSR o ISR. Le schermate private possono usare CSR.
  • Routing: Ogni URL indicizzabile ha una route unica, contenuto unico e canonical self.
  • Codici di stato: Le pagine mancanti restituiscono 404 o 410, non 200.
  • Link: La navigazione interna usa anchor crawlable con attributi href reali.
  • Metadati: Titoli, descrizioni, canonical, tag robots, tag Open Graph e schema sono specifici di route.
  • Contenuto: Copia principale, H1, info prodotto e link chiave esistono senza attendere dati client-only.
  • Performance: Peso bundle, costo di hydration, script terzi e code splitting per route sono controllati.
  • Controllo indice: Dashboard, route private, filtri low-value e pagine search sottili sono bloccati o noindex.
  • Testing: HTML iniziale, DOM renderizzato e contenuto indicizzato sono confrontati sui template importanti.
  • Visibilità AI: Il contenuto chiave appare in HTML perché molti crawler AI non renderizzano JavaScript.

«Se non viene scansionato, non può essere mostrato in search. Qualsiasi sia la surface.»

Jamie Indigo, Technical SEO Consultant @ Not a Robot

Quella frase è l’intera checklist compressa in una riga. Search, risposte AI, anteprime link e sistemi di discovery dipendono prima dall’accesso. Il ranking viene dopo.

L’architettura SPA SEO più semplice che spedirei oggi

Se partissi oggi con una SPA moderna pensando al traffico search, non renderei server-rendered l’intero prodotto. Lo dividerei.

Area del sito Approccio consigliato
Sito marketing Generazione statica
Blog e docs Generazione statica o ISR
Pagine prodotto SSR o ISR
Pagine SEO programmatiche Generazione statica con forte pruning
Dashboard CSR dietro auth
Pagine search e filtro Noindex a meno che curate manualmente
Route non valide Vere 404 o 410
Layout condiviso Metadati e navigazione server-rendered

Così lo dividerei su seojuice.io. Le pagine marketing e gli articoli devono essere HTML-first. Le superfici di prodotto che richiedono freschezza possono usare SSR o ISR. La dashboard può restare app-like perché posizionarla sarebbe inutile.

Le pagine SEO programmatiche richiedono disciplina extra. La generazione statica rende facile creare migliaia di pagine, incluse migliaia che nessuno dovrebbe indicizzare. Genera solo pagine con reale domanda di ricerca, contenuto utile e link interni. Pota il resto prima che Google debba decidere al posto tuo.

La SPA vincente non è quella che dimostra che i crawler possono eseguire JavaScript. È quella che non costringe i crawler a fare lavoro inutile.

FAQ

Una single-page application può posizionarsi su Google?

Sì. Una SPA può posizionarsi se le route indicizzabili restituiscono contenuto crawlable, metadati corretti, link interni e codici di stato validi. Google sa renderizzare JavaScript, ma affidarsi al rendering per tutto rende il sito più fragile.

Il rendering lato server è obbligatorio per la SEO di una SPA?

No, non per ogni route. L’SSR è utile per pagine pubbliche con contenuto che cambia. L’SSG o l’ISR sono spesso migliori per contenuti stabili. Il CSR va bene per dashboard private, schermate account e stati app che non dovrebbero essere indicizzati.

I route con hash sono dannosi per la SEO?

I route con hash sono una scelta povera per pagine indicizzabili. Possono andare bene per frammenti on-page, ma il contenuto pubblico dovrebbe avere URL puliti, metadati specifici di route e codici di stato a livello server.

Le pagine di risultati di ricerca di una SPA devono essere indicizzate?

Di solito no. Le pagine di ricerca interne e i filtri facet spesso generano URL sottili o duplicati. Pagine filtro curate possono essere indicizzate quando hanno domanda unica, contenuto stabile e una chiara strategia canonical.

Come faccio a sapere se la mia SPA ha un problema di soft 404?

Richiedi un URL fittizio e controlla il codice di stato. Se /questa-pagina-non-dovrebbe-esistere restituisce 200 con un messaggio client-side “not found”, hai un rischio soft 404.

Hai bisogno di aiuto per trasformare la tua SPA in pagine crawlable?

SEOJuice aiuta i team a rafforzare i link interni crawlable sulle pagine pubbliche che meritano davvero traffico search. Se la tua SPA ha route orfane, template sepolti o pagine che Google sembra non raggiungere mai, l’automazione del linking interno può rendere più semplice per i crawler seguire il layer documento.