Modern React, Vue, Angular and other SPA framework sites look great but often have serious SEO issues. Engines fetch the HTML, see a near-empty `<body>` and think "no content here". The fact that JavaScript paints the entire page after load can be invisible to engines. This article walks through how Google and Yandex handle JavaScript in 2026, what fundamentally separates SSR, SSG and CSR, and the checklist to use when a SPA site won't index.
How Google renders JavaScript
Google uses two-stage indexing for JavaScript pages. Stage 1 — crawl: Googlebot fetches the HTML and indexes what's in it. If HTML is just an empty `<div id="root"></div>` and `<script>` — Google indexes it as an empty page. Stage 2 — render: the page goes into a render queue where headless Chromium executes the JavaScript and sees the final DOM. Now Google sees content. The problem: stage 1 to stage 2 can take anywhere from hours to weeks. During that time your page sits empty in the index. If render fails (JS error, timeout, blocked resource) — stage 2 doesn't happen at all.
How Yandex renders JavaScript
Yandex lags Google in JavaScript rendering. Until 2023 Yandex barely rendered JS — only basic HTML got indexed. Since 2024 the situation improved but not radically: Yandex renders JavaScript for roughly 60% of pages in queue vs ~95% in Google, with bigger latency. Practical takeaway: if you target the Russian market and run a SPA, indexation pain in Yandex will be sharper than in Google. The fix is the same: SSR.
SSR vs SSG vs CSR: SEO differences
CSR (Client-Side Rendering) — classic SPA: the server returns empty HTML, JS fills it in the browser. The SEO disaster above. SSR (Server-Side Rendering) — the server renders full-content HTML per request, JavaScript adds interactivity later. The engine gets full content immediately. Ideal for SEO. Implemented via Next.js, Nuxt, SvelteKit and other meta-frameworks. SSG (Static Site Generation) — HTML is generated at build time, the server serves pre-built static files. Fastest option, great for SEO, but unsuitable for dynamic content (like a user dashboard). Hybrid SSR+SSG (e.g., Next.js App Router with different strategies per page) is the modern optimum. Site Metrics Tool itself runs on Next.js 16 with a hybrid SSR+SSG strategy, and indexation is excellent because of it.
How to check whether engines see your content
Test 1 — disable JavaScript in your browser (Chrome DevTools → ⚙ → Disable JavaScript), reload. If you see only an empty template, a placeholder or "Loading..." — engines see the same. Test 2 — GSC → URL Inspection → Test Live URL → View Rendered HTML. Google shows what it sees after rendering. No content = render issue on Google's side. Test 3 — `curl -A "Yandexbot" https://your-site.com/page` — what the server returns to Yandex's bot. Empty HTML = nothing for Yandex to index. These three tests in 5 minutes tell you whether you have a JavaScript SEO problem.
Fix checklist
- If SEO is mission-critical — migrate to SSR/SSG. Strongest fix. Smaller measures are stopgaps.
- Minimum-required HTML in the first response: title, meta description, h1, main text. Can be done via a server template.
- Don't block /js/ or /static/ in robots.txt — Google needs those files to render.
- Use rel=canonical everywhere, even on CSR pages — helps Google identify the canonical version.
- Don't use `pushState` for infinite scroll without server-side pagination — engines can't reach old content.
- Internal links must be real `<a href="...">`, not JavaScript `onClick` handlers. Otherwise the bot can't walk the site graph.
Frequently asked
Do React apps index well?
Depends on the rendering. React itself is neither good nor bad for SEO — what matters is how you use it. React + SSR (via Next.js) indexes great. React + pure CSR (Create React App without extras) — poorly.
Can I make Google render my site faster?
GSC → URL Inspection → Request Indexing speeds up INDEXING of a specific URL, but not RENDERING time. With CSR, changes still arrive with delay. Strategically the only fix is SSR.
Do prerender.io and similar help?
They help but it's a stopgap. Prerender generates HTML snapshots for bots via their service. Works but adds an external dependency, cost and failure point. Better to do proper SSR.