SEO pentru aplicațiile dintr-o singură pagină: de ce nu se clasează aplicațiile SPA, cum le repară SSR, generarea statică și prerandarea și cum le faci lizibile pentru crawlerele IA.

Pe această pagină
Pe scurt
o aplicație dintr-o singură pagină (SPA) încarcă o singură coajă HTML și construiește fiecare vedere cu JavaScript în browser. Google poate randa JavaScript, dar randarea este întârziată și fragilă, iar crawlerele din spatele ChatGPT, Claude și Perplexity nu îl execută deloc. Ca să te clasezi și să fii citat, fiecare vedere a unei SPA are nevoie de propriul URL, de un link real cu un href, de un titlu și o descriere unice, de un cod de stare corect și, mai ales, de conținutul principal prezent în HTML-ul trimis de server, prin randare pe server, generare statică sau prerandare.
Vrei să afli mai mult? Întreabă
Test rapid
Cine ar trebui să repare partea tehnică a site-ului tău?
Recomandarea noastră pentru tine
Dă fiecărei vederi un URL curat, parcurgibil este soluția potrivită pentru tine
Locul 1 în acest clasament, cea mai bună potrivire pentru răspunsurile tale.
Recomandarea noastră pentru tine
Folosește linkuri reale este soluția potrivită pentru tine
Locul 2 în acest clasament, cea mai bună potrivire pentru răspunsurile tale.
Recomandarea noastră pentru tine
Actualizează titlul, descrierea și canonicalul pentru fiecare rută este soluția potrivită pentru tine
Locul 3 în acest clasament, cea mai bună potrivire pentru răspunsurile tale.
Recomandarea noastră pentru tine
Returnează coduri de stare corecte este soluția potrivită pentru tine
Locul 4 în acest clasament, cea mai bună potrivire pentru răspunsurile tale.
SEO pentru aplicațiile dintr-o singură pagină este ansamblul tehnicilor care fac o aplicație JavaScript construită cu React, Vue, Angular sau Svelte la fel de ușor de parcurs de crawlere ca un site clasic. Problema este bine documentată: Google explică în bazele SEO pentru JavaScript că procesează paginile JavaScript în trei etape (crawl, randare, indexare), iar fiecare slăbiciune a unei SPA se află undeva în acest lanț. Acest ghid se concentrează pe SPA; pentru site-urile JavaScript în general, citește ghidul nostru despre SEO pentru JavaScript.
Un site tradițional returnează un document HTML complet pentru fiecare URL. O SPA returnează aproape același document pentru fiecare URL: un <div id="root"> gol, câteva meta-etichete și un pachet mare de JavaScript. Browserul descarcă pachetul, apelează un API, apoi desenează pagina. Când vizitatorul face clic pe un link, JavaScript schimbă conținutul fără reîncărcare.
Pentru un om cu un telefon rapid, rezultatul pare instant. Pentru un crawler, primul răspuns este o coajă goală: niciun titlu, niciun text, niciun link. Totul depinde de faptul că robotul execută JavaScript-ul sau nu, și când. Acest singur fapt explică majoritatea problemelor SEO ale SPA-urilor:
/#/pricing), iar partea de după # nu este trimisă niciodată serverului, deci toate vederile se prăbușesc într-un singur URL.<title>, iar dacă ruterul nu îl actualizează, fiecare pagină îl împarte cu celelalte.href: butoanele și handlerele onClick navighează pentru utilizatori, dar nu oferă nimic de urmat crawlerelor.Googlebot descarcă mai întâi HTML-ul brut și citește linkurile și directivele care se găsesc acolo. Paginile care returnează statusul 200 sunt apoi puse în coadă pentru Web Rendering Service, un Chromium fără interfață. Google afirmă că o pagină „poate rămâne în această coadă câteva secunde, dar poate dura și mai mult”. Odată randată, HTML-ul rezultat este analizat din nou pentru conținut și linkuri, apoi indexat.
Patru detalii din documentația Google contează pentru SPA-uri:
<a> cu un href sunt linkuri sigure. Linkurile injectate de JavaScript sunt în regulă atât timp cât respectă acest format.pushState) în loc de rute cu #. A abandonat vechea schemă de crawlare AJAX (URL-urile #!) în octombrie 2015.noindex din HTML-ul original câștigă. Google poate sări peste randare când vede noindex, deci eliminarea lui ulterior cu JavaScript nu funcționează.Consecința practică: Google poate indexa o SPA randată în browser, dar adaugi la fiecare pagină un pas suplimentar, o întârziere și un punct de cedare. Un timeout, un apel API blocat sau o eroare JavaScript în timpul randării lasă versiunea indexată goală. Verifică ce vede Google cu instrumentul Inspecția URL-ului din Search Console și citește ghidul nostru despre cum funcționează indexarea Google dacă paginile rămân în afara indexului.
În cea mai mare parte, nu. Într-un studiu publicat în decembrie 2024, pe traficul propriei rețele, Vercel și MERJ au constatat că „niciunul dintre marii crawleri IA nu randează în prezent JavaScript”: GPTBot, OAI-SearchBot și ChatGPT-User (OpenAI), ClaudeBot (Anthropic), PerplexityBot, Meta-ExternalAgent și Bytespider citesc doar HTML-ul brut. Ei descarcă fișierele JavaScript (aproximativ 11,5% din cererile ChatGPT și 23,8% din cele ale Claude), dar nu le rulează. Excepțiile sunt Gemini, care se bazează pe infrastructura de randare a Google, și AppleBot, care folosește un crawler bazat pe browser.
Pentru o SPA randată în client, asta înseamnă că crawlerele IA care alimentează ChatGPT, Claude și Perplexity văd o pagină goală. Produsul tău se poate clasa pe Google și totuși să fie invizibil în răspunsurile IA, pentru că asistentul nu a citit niciun cuvânt din el. Același lucru este valabil pentru majoritatea roboților de previzualizare a linkurilor din rețele sociale și din aplicațiile de mesagerie, care citesc etichetele Open Graph din HTML-ul brut. Odată ce conținutul este în HTML, verifică și că robots.txt permite crawlerele IA pe care le dorești.
Remediul este să trimiți HTML real la primul răspuns. Google numește randarea dinamică (servirea unei versiuni prerandate doar pentru roboți) „o soluție provizorie și nu o soluție recomandată” în documentația sa despre randarea dinamică și indică în schimb randarea pe server, randarea statică sau hidratarea. Definițiile de mai jos urmează referința Rendering on the Web de pe web.dev.
| Strategie | Cum funcționează | Conținut în primul HTML | Potrivită pentru | Limite |
|---|---|---|---|---|
| Randare în client (CSR) | Browserul construiește pagina din JavaScript și un API | Nu | Panouri de control și pagini din spatele unei autentificări | Indexare întârziată pe Google, invizibilă pentru majoritatea crawlerelor IA |
| Randare pe server (SSR) | Serverul randează HTML la fiecare cerere, apoi JavaScript îl hidratează | Da | Cataloage, liste, conținut care se schimbă des sau este personalizat | Cost de server, timp de răspuns mai mare dacă nu se face cache |
| Generare statică (SSG) | HTML-ul este generat la build pentru fiecare URL și servit de pe un CDN | Da | Pagini de marketing, blog, documentație, pagini de destinație | Reconstruire necesară la schimbarea conținutului (există opțiuni incrementale) |
| Prerandare la build | Un browser fără interfață capturează starea inițială a fiecărei rute ca HTML static | Da | SPA-uri existente cu un număr limitat de rute publice | Date înghețate la build, rutele trebuie listate |
| Randare dinamică | Roboții primesc o captură prerandată, utilizatorii SPA-ul | Da, doar pentru roboții listați | Remediu temporar pentru o aplicație veche | Oficial o soluție provizorie, cost de întreținere, risc de a servi roboților un conținut diferit |
Majoritatea framework-urilor moderne îți permit să combini strategiile pe rută: statică pentru paginile de marketing, randată pe server pentru catalog, randată în client pentru aplicația pentru utilizatorii autentificați. Această configurație hibridă oferă crawlerelor HTML complet acolo unde se întâmplă traficul din căutare și păstrează experiența SPA acolo unde aduce valoare.
| Bibliotecă | Framework sau funcție pentru HTML la prima încărcare |
|---|---|
| React | Next.js (componente de server, SSR și generare statică), React Router în modul framework, Gatsby |
| Vue | Nuxt (randare universală implicit, generare statică disponibilă) |
| Angular | Angular SSR (randare pe server și prerandare la build) |
| Svelte | SvelteKit (randare pe server implicit, prerandare pe rută) |
| Oricare dintre ele | Astro (HTML static implicit, insule interactive încărcate doar acolo unde e nevoie) |
Site-urile generate de constructorii de site-uri cu IA merită o mențiune aparte: multe exportă o aplicație React randată în client. Dacă ți-ai construit site-ul cu unul dintre ei, citește notele noastre despre SEO și GEO pentru Lovable înainte să presupui că Google și ChatGPT pot citi site-ul.
Folosește History API (/pricing, niciodată /#/pricing), câte un URL pentru fiecare bucată de conținut și același URL indiferent dacă vizitatorul sosește direct sau prin navigare în aplicație. Fiecare URL trebuie să încarce conținutul corect când este deschis într-un tab nou, iar acesta este testul pe care îl face un crawler.
Fiecare element de navigare care duce spre o pagină indexabilă ar trebui să fie un <a href="/cale">. Componentele de link ale framework-urilor (Link, NuxtLink, routerLink) produc acest markup; handlerele de clic pe elemente div sau button nu. Linkurile bune poartă și arhitectura site-ului: dacă o pagină nu este legată, crawlerele rareori o găsesc.
Fiecare rută are nevoie de propriul titlu, de propria meta-descriere, de propriul canonical și de etichetele Open Graph, generate pe server când este posibil. Pagina noastră despre meta-etichete enumeră ce trebuie setat. Păstrează o singură etichetă canonical: Google recomandă s-o setezi în HTML, iar dacă JavaScript o modifică, rezultatul nu trebuie să contrazică originalul.
Produsele care lipsesc și articolele șterse nu trebuie să răspundă 200 cu un mesaj de eroare. Cu SSR, returnează un 404 sau 410 real de la server. Într-o SPA pură, Google acceptă două soluții de rezervă: redirecționare cu JavaScript către un URL care returnează 404 sau o etichetă meta robots noindex pe vederea de eroare.
Titlurile, textul, prețurile, FAQ-ul și datele structurate JSON-LD ar trebui să fie în răspunsul serverului, nu încărcate după un clic sau un scroll. Conținutul din spatele filelor randate la cerere sau al butoanelor „încarcă mai mult” este adesea ratat.
Împarte pachetul pe rută, amână ce nu este necesar pentru prima vedere și evită re-randarea întregii pagini în timpul hidratării. Reține că datele de teren Chrome (CrUX) atribuie metricile navigărilor din aplicație URL-ului pe care vizitatorul l-a încărcat prima dată, deci testează individual șabloanele-cheie.
Compară trei versiuni ale fiecărui șablon important: HTML-ul brut (vezi sursa sau descarcă pagina cu un instrument din linia de comandă), HTML-ul randat de Google (Inspecția URL-ului, apoi „Vezi pagina parcursă”) și pagina cu JavaScript dezactivat. Dacă textul principal apare doar în a doua versiune, crawlerele IA nu îl văd. Auditul gratuit de parcurgere pentru IA și verificatorul de indexabilitate rulează aceste verificări pe orice URL.
| Simptom | Cauza probabilă | Remediu |
|---|---|---|
| Search Console arată multe pagini „Parcurse, dar neindexate în prezent” | HTML gol sau aproape identic înainte de randare | SSR, SSG sau prerandare pentru rutele publice |
Fiecare rezultat dintr-o căutare site: arată același titlu | Titlul nu este actualizat pe rută | Gestionarea capului paginii pe rută, pe server |
| Doar pagina principală este indexată | Rutare cu fragmente sau linkuri fără href | History API și linkuri <a> reale |
| Paginile de eroare apar în index | Soft 404 (status 200 peste tot) | 404 de pe server, sau redirecționare JavaScript către un URL 404, sau noindex |
| Se clasează pe Google, dar nu este citată niciodată de ChatGPT sau Perplexity | Conținut vizibil doar după execuția JavaScript | Conținut în primul răspuns HTML |
| Vechi conținut afișat în vederea randată de Google | Fișiere JavaScript sau CSS din cache | Nume de fișiere cu amprentă |
Timp de ani, randarea în client a fost un risc gestionabil, pentru că Google randa JavaScript într-un final. Acum că o parte din descoperire se face în ChatGPT, Claude, Gemini și Perplexity, costul s-a schimbat: o pagină care există doar după execuția JavaScript lipsește din sursele pe care le pot citi majoritatea asistenților. Parcurgerea HTML-ului brut a devenit prima condiție a optimizării pentru motoarele generative.
Odată ce HTML-ul este complet, restul urmează regulile obișnuite: paginile care răspund clar la o întrebare, cu fapte susținute de surse și date structurate, sunt cele pe care asistenții le citează. Funcțiile de optimizare GEO ale Sorank te ajută să scrii și să publici acest conținut, iar Urmărirea mențiunilor IA arată dacă ChatGPT, Claude și Gemini îți citează brandul după remedierea randării.
Regula-cheie a SEO pentru aplicațiile dintr-o singură pagină încape într-o propoziție: tot ce vrei ca Google să clasifice și IA să citeze trebuie să fie în HTML-ul trimis de server. Păstrează SPA-ul pentru experiența utilizatorilor autentificați, randează paginile publice pe server sau la build, apoi testează ce primesc roboții înainte și după fiecare lansare.
O aplicație dintr-o singură pagină nu este penalizată de Google, dar configurarea ei implicită, randarea în client cu o singură coajă HTML, face indexarea mai lentă și mai puțin sigură. Majoritatea crawlerelor IA nu execută JavaScript, deci văd o pagină goală. Cu randare pe server, generare statică sau prerandare pe rutele publice, o SPA se poate clasa la fel de bine ca orice site clasic.
React în sine este neutru: contează unde se produce HTML-ul. O aplicație React randată doar în browser are problemele obișnuite ale SPA-urilor, în timp ce aceleași componente randate pe server cu Next.js sau React Router în modul framework livrează HTML complet crawlerelor. Alege un framework care susține randarea pe server sau statică pentru paginile pe care vrei să le indexezi.
Doar ca măsură temporară. Google descrie randarea dinamică drept o soluție provizorie și nu o soluție recomandată, pentru că menținerea unei versiuni separate pentru roboți adaugă cost și risc. Randarea pe server, generarea statică sau prerandarea la build oferă același HTML fiecărui vizitator și sunt remediile pe termen lung.
AU ÎNCERCAT SORANK ÎNAINTEA TA
