TL;DR: Per impostazione predefinita, le single-page application creano problemi SEO ai motori di ricerca. Google mette in coda le pagine JavaScript per il rendering — un processo che può richiedere da ore a giorni — e i crawler AI (GPTBot, ClaudeBot, PerplexityBot) non eseguono affatto JavaScript. La soluzione è il rendering lato server tramite Next.js, Nuxt, Angular SSR o SvelteKit. In questa guida trovi la configurazione esatta per ogni framework, con codice, passaggi di test e il panorama del rendering nel 2026.
Le single-page application caricano un guscio HTML iniziale e poi lo riempiono con JavaScript. Per l’utente l’esperienza è veloce, quasi da app nativa. Googlebot, invece, spesso riceve nient’altro che un semplice <div id="app"></div> vuoto.


Ho fatto audit su centinaia di single-page application tramite SEOJuice. La dinamica è sempre la stessa: il sito è bellissimo nel browser, JavaScript gira alla perfezione, e i motori di ricerca non vedono quasi nulla. O peggio — vedono i contenuti giorni dopo, dopo essere rimasti bloccati nella coda di rendering di Google. Il bug degli URL hash in Angular, da solo, è costato ai clienti più traffico organico di qualsiasi aggiornamento dell’algoritmo che io ricordi. Un cliente ecommerce che usava Angular con HashLocationStrategy aveva 1,200 pagine prodotto. Google ne vedeva esattamente una: la pagina iniziale. Tutto ciò che veniva dopo il # era invisibile. Non è un piccolo calo di ranking. È il 60% del loro fatturato organico sparito per una configurazione di routing che richiede due minuti per essere corretta, se sai dove guardare.
Ecco come funziona davvero la pipeline di rendering di Google:
Quella coda tra il passaggio 2 e il passaggio 3? Può richiedere da pochi secondi a giorni. I tuoi competitor che servono HTML lato server la saltano del tutto — i loro contenuti possono essere indicizzati già al primo crawl.
Ma c’è di peggio. Nel 2025, Vercel ha analizzato oltre un miliardo di richieste dei crawler e ha scoperto che la maggior parte dei crawler AI non esegue affatto JavaScript. GPTBot, ClaudeBot, PerplexityBot — leggono HTML grezzo, non renderizzato. Un’analisi di oltre mezzo miliardo di fetch di GPTBot non ha trovato alcuna evidenza di esecuzione JavaScript. Se la tua single-page application si basa sul rendering lato client, i tuoi contenuti sono invisibili ai sistemi che alimentano ChatGPT, Claude e la ricerca di Perplexity.
"Se il tuo sito Next.js serve pagine critiche come SPA dipendenti da JavaScript, quelle pagine sono inaccessibili ai sistemi che stanno plasmando il modo in cui le persone scoprono le informazioni."
Non è un problema di nicchia. Se vuoi che i tuoi contenuti vengano scoperti sia da Google sia dai motori di ricerca AI nel 2026, il rendering lato server non è più opzionale — è un prerequisito.
Ci sono quattro modi per renderizzare una single-page application. La scelta determina se i motori di ricerca vedranno i tuoi contenuti subito, più tardi o mai.
| Approccio | Come funziona | Impatto SEO | Tempo al primo byte (TTFB) | Ideale per |
|---|---|---|---|---|
| CSR (Client-Side Rendering) | Il browser scarica un guscio HTML vuoto, poi JavaScript compone la pagina | Scarso — Google mette in coda il rendering, i crawler AI non vedono nulla | Veloce (ma vuoto) | Dashboard interne, pannelli admin, pagine protette da login |
| SSR (Server-Side Rendering) | Il server genera HTML completo per ogni richiesta e invia la pagina già pronta | Eccellente — contenuto completo già al primo crawl | Variabile (dipende dal tempo di elaborazione del server) | Contenuti dinamici: e-commerce, news, contenuti generati dagli utenti |
| SSG (Static Site Generation) | Le pagine vengono generate in anticipo al deploy come HTML statico | Eccellente — caricamento rapidissimo, completamente scansionabile | Il più veloce (servito da CDN) | Blog, documentazione, pagine marketing, landing page |
| ISR (Incremental Static Regeneration) | Pagine statiche che si rigenerano a intervalli o on-demand | Eccellente — velocità di SSG con contenuti sempre freschi | Veloce (cache con rigenerazione in background) | Siti grandi con contenuti che cambiano periodicamente (cataloghi prodotto, pagine elenco) |
Punto chiave
Qualsiasi pagina che vuoi far posizionare su Google o sui motori di ricerca AI deve essere renderizzata lato server o generata in anticipo. Il CSR va bene per pagine protette da login e dashboard. Per tutto ciò che è pubblico, usa SSR, SSG o ISR.
La regola è semplice: se un URL deve posizionarsi in ricerca, deve restituire HTML completo nella risposta iniziale. Nessuna eccezione. E no, non vale il solito “tanto Google ormai renderizza JavaScript”. Sì, Google ci prova — a volte, prima o poi, in modo poco affidabile — e i crawler AI non ci provano nemmeno. Ho avuto questa discussione con sviluppatori frontend più volte di quante riesca a contare. Di solito la conversazione finisce quando mostro il loro sito nello strumento Controllo URL di Google e vedono una pagina vuota dove dovrebbe esserci la loro splendida UI.
React puro (Create React App, Vite con React) è solo CSR. Google farà fatica a interpretarlo e indicizzarlo correttamente. Next.js è la risposta — e da quando App Router è diventato l’impostazione predefinita in Next.js 13+, dal punto di vista SEO le cose sono migliorate molto.
Con App Router, i componenti vengono renderizzati lato server per impostazione predefinita. Aggiungi 'use client' solo quando un componente ha bisogno delle API del browser o di interattività. Questo significa che la maggior parte del contenuto della tua pagina viene servita come HTML puro — senza dipendere dal rendering JavaScript nel browser.
// app/blog/[slug]/page.tsx — Server Component (default)
import { Metadata } from 'next'
// Dynamic metadata for each blog post
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug)
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
type: 'article',
publishedTime: post.publishedAt,
},
alternates: {
canonical: `https://example.com/blog/${params.slug}`,
},
}
}
// This component runs on the server — zero JS shipped to the browser
export default async function BlogPost({ params }) {
const post = await getPost(params.slug)
return (
<article>
<h1>{post.title}</h1>
<div>{post.content}</div>
</article>
)
}
Per contenuti che non cambiano spesso (articoli del blog, landing page), genera le pagine in anticipo in fase di build:
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getAllPosts()
return posts.map((post) => ({ slug: post.slug }))
}
// Combined with the page component above,
// Next.js generates static HTML at build time for every post
Per siti ecommerce con migliaia di prodotti, usa ISR per rivalidare le pagine a intervalli programmati:
// app/products/[id]/page.tsx
export const revalidate = 3600 // Regenerate every hour
export default async function ProductPage({ params }) {
const product = await getProduct(params.id)
return <ProductDetail product={product} />
}
Se sei bloccato su React puro e non puoi migrare a Next.js, usa un servizio di pre-rendering come Prerender.io come soluzione tampone. Ma capisci bene una cosa: è nastro adesivo, non una vera soluzione. Ogni mese in cui rimandi la migrazione è un mese di indicizzazione subottimale.
Stessa storia, ecosistema diverso. Vue puro con Vue Router è solo CSR. Nuxt 3 ti offre SSR, SSG, ISR ed edge rendering con Nitro — tutto in un unico framework.
Nuxt 3 usa l’universal rendering già pronto. Nessuna configurazione necessaria — le tue pagine vengono renderizzate lato server al primo caricamento, poi idratate per la navigazione lato client.
<!-- pages/blog/[slug].vue -->
<script setup>
const route = useRoute()
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`)
// Per-page SEO metadata
useHead({
title: post.value.title,
meta: [
{ name: 'description', content: post.value.excerpt },
{ property: 'og:title', content: post.value.title },
{ property: 'og:description', content: post.value.excerpt },
],
link: [
{ rel: 'canonical', href: `https://example.com/blog/${route.params.slug}` }
]
})
</script>
<template>
<article>
<h1>{{ post.title }}</h1>
<div v-html="post.content" />
</article>
</template>
Le routeRules di Nuxt 3 ti permettono di mescolare strategie di rendering nella stessa app. È molto potente per siti che hanno sia pagine marketing statiche sia contenuti dinamici:
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // SSG — homepage
'/blog/**': { isr: 3600 }, // ISR — blog posts regenerate hourly
'/products/**': { ssr: true }, // SSR — dynamic product pages
'/dashboard/**': { ssr: false }, // CSR — authenticated dashboard
}
})
Nitro, il motore server di Nuxt 3, supporta il deploy su piattaforme edge (Cloudflare Workers, Vercel Edge, Netlify Edge). Questo significa che le tue pagine SSR vengono renderizzate nei nodi CDN più vicini all’utente — un TTFB sotto i 50ms è realistico. Dal punto di vista SEO, significa caricamenti più rapidi, Core Web Vitals migliori e crawl più frequenti da parte di Google.
Storicamente Angular è stato il framework più difficile da ottimizzare per la SEO. La situazione è cambiata parecchio da Angular 17, che ha reso SSR un cittadino di prima classe con supporto integrato per l’hydration. Niente più Angular Universal appiccicato sopra come ripensamento.
I nuovi progetti ottengono SSR di default quando usi la CLI:
# New project with SSR enabled
ng new my-app --ssr
# Add SSR to an existing project
ng add @angular/ssr
// product-page.component.ts
import { Component, OnInit } from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-product-page',
template: `
<article>
<h1>{{ product.name }}</h1>
<p>{{ product.description }}</p>
</article>
`
})
export class ProductPageComponent implements OnInit {
product: any;
constructor(
private meta: Meta,
private title: Title,
private route: ActivatedRoute,
private productService: ProductService
) {}
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.productService.getProduct(id).subscribe(product => {
this.product = product;
this.title.setTitle(product.name);
this.meta.updateTag({ name: 'description', content: product.description });
this.meta.updateTag({ property: 'og:title', content: product.name });
});
}
}
Angular 19.2 ha introdotto l’incremental hydration, basandosi sull’API @defer. I componenti generano HTML completo sul server ma vengono idratati sul client solo quando scatta un trigger (nel viewport, all’interazione, ecc.). Questo riduce il JavaScript inviato al browser mantenendo comunque tutto il contenuto SSR disponibile ai crawler.
Problema tipico specifico di Angular
Il routing basato su hash (HashLocationStrategy) produce URL come example.com/#/products. Google ignora tutto ciò che viene dopo il #. Il tuo catalogo prodotti da 500 pagine appare come una sola pagina. Passa subito a PathLocationStrategy — è il default in Angular, ma alcuni progetti legacy usano ancora l’hash routing. È esattamente il bug che è costato al cliente ecommerce citato sopra il 60% del traffico organico. Erano andati avanti con hash routing per due anni. Due anni di pagine prodotto che Google non sapeva nemmeno esistessero. La correzione ha richiesto 20 minuti. Il recupero, quattro mesi.
SvelteKit è diventato in silenzio uno dei migliori framework per la SEO pronti all’uso. SSR è attivo di default — dovresti proprio disattivarlo volontariamente. Inoltre il framework compila via il framework stesso, spedendo molto meno JavaScript rispetto a React o Angular.
Ogni pagina SvelteKit viene renderizzata lato server per impostazione predefinita. I tuoi file +page.svelte generano HTML completo alla prima richiesta:
<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
export let data;
</script>
<svelte:head>
<title>{data.post.title}</title>
<meta name="description" content={data.post.excerpt} />
<link rel="canonical" href={`https://example.com/blog/${data.post.slug}`} />
</svelte:head>
<article>
<h1>{data.post.title}</h1>
{@html data.post.content}
</article>
// src/routes/blog/[slug]/+page.server.ts
export async function load({ params }) {
const post = await getPost(params.slug);
return { post };
}
Come Nuxt, anche SvelteKit ti permette di controllare il rendering per singola route:
// src/routes/blog/[slug]/+page.ts
export const prerender = true; // SSG — generate at build time
// src/routes/dashboard/+page.ts
export const ssr = false; // CSR-only for authenticated content
Perché SvelteKit merita attenzione lato SEO: il compilatore elimina il runtime del framework. Una pagina SvelteKit invia una frazione del JavaScript rispetto a una pagina equivalente in Next.js o Nuxt. Meno JavaScript significa LCP più veloce, punteggi INP migliori e Core Web Vitals più sani — tutti segnali di ranking.
Ogni single-page application deve superare questi controlli. Sono ordinati per impatto — sistema prima gli elementi in alto.
| # | Controllo | Perché conta | Come risolvere |
|---|---|---|---|
| 1 | SSR o SSG attivi su tutte le pagine pubbliche | Senza, Google mette in coda le tue pagine e i crawler AI non vedono nulla | Next.js App Router, Nuxt 3, Angular SSR o SvelteKit |
| 2 | URL puliti (senza frammenti hash) | Gli URL hash (#/page) sono invisibili ai motori di ricerca | Usa routing basato sulla history — l’impostazione predefinita in tutti i framework moderni |
| 3 | Title tag unico per pagina | Lo stesso title su ogni route significa che Google ne sceglie uno e ignora gli altri | generateMetadata (Next.js), useHead() (Nuxt), servizio Meta (Angular), <svelte:head> |
| 4 | Meta description unica per pagina | Controlla il tuo snippet nei risultati di ricerca | Stesse librerie dei title tag — impostala per route |
| 5 | Canonical tag su ogni pagina | Previene problemi di contenuto duplicato causati da query param e trailing slash | Aggiungi <link rel="canonical"> per pagina nei metadata |
| 6 | Gerarchia corretta degli heading (H1 > H2 > H3) | Segnala la struttura del contenuto ai crawler | Un solo H1 per pagina, nesting logico nei componenti |
| 7 | I link interni usano veri tag <a href> | La navigazione solo JavaScript (handler onClick) blocca i crawler | Usa i componenti Link del framework: <Link>, <NuxtLink>, routerLink |
| 8 | Sitemap XML inviata | Aiuta Google a scoprire pagine non raggiungibili tramite link | Generala con next-sitemap, nuxt-simple-sitemap o tool specifici del framework |
| 9 | Code splitting e lazy loading | Riduce il bundle JS iniziale, migliora LCP e INP | Import dinamici (next/dynamic, defineAsyncComponent, @defer) |
| 10 | Schema markup (JSON-LD) sulle pagine chiave | Abilita rich snippet e aiuta i crawler AI a capire il contenuto | JSON-LD nel <head> o nel <body> — renderizzato lato server, non iniettato via JS |
Questi sono gli errori che vedo in quasi ogni audit di single-page application. Ognuno di loro, senza eccezioni, distrugge il ranking.
“Ma Google renderizza JavaScript!” — sì, a volte, prima o poi, se il tuo JS non genera errori, se la coda di rendering non è intasata, se JavaScript non va in timeout e se nessuno script di terze parti interferisce con il rendering. Sono un bel po’ di “se” su cui scommettere il tuo traffico organico. E i crawler AI non ci provano nemmeno.
// WRONG — CSR-only React app
// Google sees: <div id="root"></div>
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
// RIGHT — Next.js Server Component
// Google sees: fully rendered HTML with all content
export default async function Page() {
const data = await fetchData();
return <Article data={data} />;
}
HashLocationStrategy di Angular e la modalità hash di Vue Router producono URL come example.com/#/products/shoes. Google ignora tutto ciò che viene dopo il #. L’intera applicazione appare come una sola pagina.
// WRONG — Vue Router hash mode
const router = createRouter({
history: createWebHashHistory(), // URLs: example.com/#/about
routes
})
// RIGHT — Vue Router history mode
const router = createRouter({
history: createWebHistory(), // URLs: example.com/about
routes
})
Le single-page application partono con un solo <title> nel guscio HTML iniziale. Se non lo aggiorni dinamicamente per ogni route, ogni pagina avrà lo stesso title. Google indicizzerà una versione e ignorerà le altre.
<!-- WRONG — static HTML shell with one title -->
<!DOCTYPE html>
<html>
<head>
<title>My App</title> <!-- Same for every route -->
</head>
<body><div id="app"></div></body>
</html>
<!-- RIGHT — dynamic metadata per route (Nuxt example) -->
<script setup>
useHead({
title: `${product.name} | MyStore`,
meta: [{ name: 'description', content: product.summary }]
})
</script>
Un singolo errore non gestito nella tua applicazione può impedire il rendering dell’intera pagina. Il Web Rendering Service di Google non riprova. La pagina resta vuota nell’indice.
Lo vedo continuamente: uno script analytics di terze parti genera un errore, oppure una risposta API mancante manda in crash l’albero dei componenti. Il risultato? Google indicizza una pagina vuota. Un cliente aveva uno snippet Hotjar che occasionalmente falliva nel renderer di Google. Le loro pagine prodotto apparivano casualmente vuote nello strumento Controllo URL di GSC. La soluzione è stata aggiungere un error boundary attorno all’inizializzazione degli analytics. Tempo richiesto: 10 minuti. Aveva danneggiato silenziosamente la loro indicizzazione per mesi.
Soluzione: aggiungi error boundary in React (componenti ErrorBoundary), usa NuxtErrorBoundary in Nuxt e testa sempre con JavaScript disattivato (ci arrivo tra poco).
Le single-page application con routing lato client non espongono la loro struttura URL tramite link HTML come fanno i siti multipagina. Senza sitemap, Google scopre le pagine solo tramite link scansionabili — e se il tuo internal linking è guidato da JavaScript, potrebbe non trovare nulla.
# Install next-sitemap for Next.js
npm install next-sitemap
# next-sitemap.config.js
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
changefreq: 'weekly',
// Exclude routes that shouldn't be indexed
exclude: ['/dashboard/*', '/api/*', '/admin/*'],
}
Se il tuo robots.txt blocca file CSS o JS, il renderer di Google non può costruire la tua pagina. Lo vediamo sorprendentemente spesso — di solito è una configurazione predefinita rimasta lì per sbaglio.
# WRONG — blocking JS and CSS
User-agent: *
Disallow: /static/js/
Disallow: /static/css/
# RIGHT — allow all resources needed for rendering
User-agent: *
Disallow: /api/
Disallow: /dashboard/
Allow: /static/

Non dare per scontato che la tua single-page application sia scansionabile solo perché funziona in Chrome. Ecco come verificare cosa vedono davvero i motori di ricerca.
Lo strumento Controllo URL è la tua migliore diagnostica in assoluto. Inserisci un URL qualsiasi e clicca su “Test URL pubblicato”. Google recupererà la tua pagina, la renderizzerà con il suo Web Rendering Service e ti mostrerà il risultato.
Cosa controllare:
Il nostro tool gratuito di audit SEO analizza la tua single-page application alla ricerca di problemi di rendering, meta tag mancanti, link rotti e problemi di accessibilità. Ti mostra esattamente cosa vedono i motori di ricerca — senza login, risultati in 30 secondi.
Dato che i crawler AI non renderizzano JavaScript, verifica se riescono ad accedere ai tuoi contenuti usando l’AI Crawler Inspector. Simula il modo in cui GPTBot, ClaudeBot e altri bot AI vedono le tue pagine.
Il panorama SEO delle single-page application nel 2026 è sostanzialmente diverso rispetto anche solo a due anni fa. Ecco cosa conta davvero.
Con Next.js App Router, i componenti vengono renderizzati lato server per impostazione predefinita. Passi esplicitamente al rendering lato client con 'use client'. Questo ribalta il vecchio modello — invece di avere tutto in CSR con SSR aggiunto sopra, hai tutto in rendering lato server con il lato client aggiunto solo dove serve. Le implicazioni SEO sono enormi: gran parte della tua applicazione viene servita automaticamente come HTML puro.
Nuxt 3 con Nitro, Next.js Edge Runtime e gli adapter di SvelteKit ora distribuiscono SSR nei nodi edge della CDN (Cloudflare Workers, Vercel Edge Functions). Le tue pagine vengono renderizzate nel nodo edge più vicino all’utente — o al crawler. Un TTFB sotto i 50ms è raggiungibile a livello globale.
Angular 17+ ha integrato SSR nella CLI con ng new --ssr. Angular 19 ha aggiunto l’incremental hydration. I tempi delle configurazioni dolorose di Angular Universal sono finiti. Se stai ancora usando un’app Angular basata esclusivamente su CSR, oggi il percorso di migrazione è finalmente lineare.
GPTBot, ClaudeBot, PerplexityBot e altri stanno crawlando il web per costruire dati di training e alimentare la ricerca AI. Nessuno di loro esegue JavaScript. L’analisi di oltre mezzo miliardo di richieste GPTBot non ha trovato alcuna evidenza di esecuzione JS. Se vuoi che i tuoi contenuti vengano citati nelle risposte generate dall’AI, SSR è l’unica opzione.
"Vedere l’HTML renderizzato, non solo il codice sorgente, è importante per diagnosticare se c’è un problema di indicizzazione. Google può scoprire i tuoi link solo se sono elementi HTML
<a>con un attributohref."
LCP, INP e CLS restano segnali di ranking. Le single-page application che distribuiscono bundle JavaScript pesanti vengono penalizzate su LCP (la pagina impiega troppo a mostrare contenuti significativi) e su INP (le interazioni risultano lente). Code splitting, lazy loading e JavaScript lato client ridotto al minimo non sono opzionali — sono requisiti di performance che impattano direttamente il ranking.
"Il prerendering statico o lato server del tuo sito è la best practice per la SEO — rende i crawler più propensi a reindicizzare il tuo sito più frequentemente."
Non sai quale framework scegliere? Ecco come si confrontano dal punto di vista SEO.
| Funzionalità | Next.js (React) | Nuxt 3 (Vue) | Angular SSR | SvelteKit |
|---|---|---|---|---|
| SSR di default | Sì (App Router) | Sì | Sì (dalla v17) | Sì |
| Generazione statica | generateStaticParams | prerender: true | ng build --prerender | export const prerender = true |
| Supporto ISR | Integrato (revalidate) | Integrato (isr: seconds) | Manuale tramite service worker | Tramite configurazione specifica dell’adapter |
| Edge rendering | Vercel Edge, Cloudflare | Nitro (multi-platform) | Limitato | Più adapter |
| API metadata per pagina | generateMetadata | useHead() | Servizi Meta + Title | <svelte:head> |
| JavaScript client distribuito | Moderato (RSC aiuta) | Moderato | Pesante | Minimo (compilato via) |
| Community/ecosistema | Il più grande | Solido | Orientato enterprise | In rapida crescita |
Sì, ma con riserve. Il Web Rendering Service di Google usa un browser Chromium headless per eseguire JavaScript e renderizzare le single-page application. Tuttavia questo rendering avviene in una coda separata dopo il crawl iniziale, e può ritardare l’indicizzazione da ore a giorni. Le pagine con errori JavaScript potrebbero non essere mai renderizzate. Per un’indicizzazione affidabile, usa SSR o SSG — non affidarti alla coda di rendering di Google per contenuti sensibili al fattore tempo.
Una single-page application basata esclusivamente su CSR fa male alla SEO. Una single-page application con rendering lato server no. Il framework non è il punto — conta se la risposta HTML iniziale contiene o no i tuoi contenuti. Next.js, Nuxt, Angular SSR e SvelteKit producono tutti SPA completamente scansionabili. Il problema “SPA vs SEO” è stato risolto anni fa; il vero problema sono gli sviluppatori che non implementano la soluzione.
Per qualsiasi pagina che deve posizionarsi in ricerca? Sì. React da solo (tramite Vite o Create React App) è solo CSR — i motori di ricerca vedono una pagina vuota. Next.js aggiunge SSR, SSG e ISR. Con React Server Components in App Router, la maggior parte dei componenti viene renderizzata lato server di default. Se la tua app React serve contenuti pubblici, Next.js è la soluzione standard.
Non le gestiscono. GPTBot (OpenAI), ClaudeBot (Anthropic), PerplexityBot e altri crawler AI non eseguono JavaScript. Analizzano solo HTML grezzo. L’analisi di oltre mezzo miliardo di richieste GPTBot non ha trovato alcuna evidenza di rendering JavaScript. Se i tuoi contenuti sono renderizzati lato client, sono invisibili ai motori di ricerca AI. SSR è l’unico modo per comparire nelle risposte e nelle citazioni generate dall’AI.
SSR (Server-Side Rendering) genera HTML a ogni richiesta — ideale per contenuti dinamici. SSG (Static Site Generation) genera HTML in fase di build — è il più veloce ma richiede nuove build quando i contenuti cambiano. ISR (Incremental Static Regeneration) genera pagine statiche che si rigenerano automaticamente a intervalli — combina la velocità di SSG con contenuti aggiornati. Tutti e tre consegnano HTML completo ai motori di ricerca già alla prima richiesta. Scegli in base a quanto spesso cambiano i tuoi contenuti.
Le single-page application non sono intrinsecamente negative per la SEO. Ma le SPA basate esclusivamente su CSR sì, e nel 2026 sono invisibili anche ai motori di ricerca AI.
La soluzione esiste da anni. Next.js, Nuxt 3, Angular SSR e SvelteKit forniscono tutti HTML lato server già pronto. React Server Components ha reso il default ancora migliore — gran parte della tua app viene renderizzata automaticamente sul server. Non c’è alcuna scusa per pubblicare una single-page application accessibile al pubblico senza rendering lato server.
Se non sei sicuro che la tua single-page application sia scansionabile, fai un audit gratuito — richiede 30 secondi e ti mostra esattamente cosa vede Google. Per la visibilità verso i crawler AI, controlla l’AI Crawler Inspector.
Letture correlate:
no credit card required