Is client-side rendering bad for SEO? What Google and AI bots see
Google renders JavaScript later, in a queue; most AI crawlers never run it. How to test what each sees in a React SPA, and the fixes that work.
LLaunchScaler·Published ·8 min read
Client-side rendering is not fatal on Google, but it is a real problem everywhere else. Googlebot renders JavaScript in a deferred queue, so a React single-page app can be indexed, just later and only if rendering works; most AI crawlers, including OpenAI's, Anthropic's and Perplexity's, do not execute JavaScript at all, so they see only the empty HTML shell.
So the answer depends on who you need to reach. The test is the same for all of them: compare the raw HTML your server sends with the page your browser shows.
Does Google render JavaScript?
Yes. Google processes JavaScript apps in three phases: crawling, rendering and indexing. Every page that returns a 200 goes into a rendering queue, and once Google's resources allow, a headless, evergreen Chromium runs the JavaScript and Google indexes the rendered HTML. Google says a page "may stay on this queue for a few seconds, but it can take longer than that."
That delay and dependency are where client-side rendering costs you on Google:
Content is only seen after rendering, so it is indexed later than content in the HTML response.
If a script fails, times out or depends on a blocked resource, the rendered page is missing content.
Google won't render JavaScript from blocked files or pages, so a robots.txt rule on /assets/ or /static/ can hide your whole app.
A noindex in the original HTML may stop rendering entirely. Google warns that removing it with JavaScript "may not work as expected."
Client-side routing often can't return meaningful status codes, which produces soft 404s. Google suggests a JavaScript redirect to a URL that returns 404, or a JavaScript-added noindex, for error views.
Routes behind # fragments (/#/pricing) are not reliably resolved as separate URLs. Use the History API and real <a href="/pricing"> links.
Questions, answered
What people ask about this
01
Does Google render JavaScript?
Yes. Googlebot queues every page that returns 200 for rendering, and a headless Chromium runs the JavaScript once Google's resources allow. Google says the wait can be a few seconds or longer, so client-rendered content is indexed later than content in the HTML, and missed if rendering fails.
Google's own summary is the useful one: server-side or pre-rendering "is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript."
Do AI crawlers render JavaScript?
Most do not. Vercel analysed crawler traffic across its network and found that none of the major AI crawlers it measured render JavaScript. ChatGPT's and Claude's crawlers do fetch JavaScript files (11.50% and 23.84% of their requests) but do not execute them, so they cannot read content a script adds after load.
Crawler
Runs JavaScript?
What it reads from a client-rendered app
OpenAI: OAI-SearchBot, ChatGPT-User, GPTBot
No
The HTML shell
Anthropic: ClaudeBot
No
The HTML shell
PerplexityBot
No
The HTML shell
Meta-ExternalAgent, Bytespider
No
The HTML shell
Common Crawl (CCBot)
No
The HTML shell
Gemini (through Googlebot's infrastructure)
Yes
The rendered page
Applebot
Yes
The rendered page
Googlebot
Yes, deferred
The rendered page, after the queue
Vercel notes one nuance: content included in the initial HTML response, such as JSON data or streamed React Server Component payloads, can still be read, because AI models interpret non-HTML content. A client-side app that fetches everything after load leaves nothing to read. The guide to whether AI crawlers render JavaScript goes crawler by crawler.
Link-preview bots behave similarly. Lovable's docs, for example, say social platforms such as LinkedIn, Slack, Facebook, X and WhatsApp usually read Open Graph tags straight from the HTML response and often do not run client-side JavaScript, which is why React Helmet tags so often fail in link previews.
How do you test what crawlers see in your React app?
Fetch the page without a browser and look for your content. curl returns the raw HTML a non-rendering crawler receives; the Elements panel in your browser shows the DOM after JavaScript ran. If a sentence from the page appears only in the second, crawlers that don't render cannot see it.
Pick a sentence from the page, ideally the H1.
Run curl -s https://yoursite.com/pricing | grep -i "your headline". No output means the text is not in the HTML.
Look at the raw HTML in full: curl -s https://yoursite.com/pricing | head -50. A typical client-rendered shell is a <div id="root"></div> and a script tag.
In Chrome, open DevTools, open the command menu (Cmd+Shift+P on Mac, Ctrl+Shift+P on Windows and Linux), run Disable JavaScript and reload. What you see now is roughly what a non-rendering crawler gets. It stays off only while DevTools is open.
For Google specifically, use URL Inspection in Search Console, click Test live URL, then View tested page. The Screenshot tab shows the page as Google's inspection tool rendered it.
Run the test on the production URL, not localhost, and on a deep page as well as the homepage, since routes can behave differently.
What must be in the raw HTML?
Everything a crawler needs to understand and list the page: the title, meta description, canonical, robots directives, Open Graph tags, structured data, the main heading and body copy, and internal links as real <a href> elements. Anything added only by JavaScript is invisible to non-rendering crawlers and delayed for Google.
Element
Why it must be in the HTML
<title> and meta description
The text search results and AI answers show
<link rel="canonical">
Google says not to change it with JavaScript to anything other than the value in the original HTML
<meta name="robots">
A noindex in the original HTML can stop Google rendering at all
Open Graph and Twitter tags
Link-preview bots read the served HTML
JSON-LD structured data
Only counts if a crawler sees it
H1 and main content
What non-rendering AI crawlers can quote
<a href> links to other pages
How crawlers discover the rest of the site
Does client-side rendering hurt page speed too?
It can, and speed is the other half of the SEO cost. web.dev's guide to rendering on the web says the JavaScript a client-rendered app needs "tends to grow as an application grows, which can impact a page's INP," and that keeping large bundles in check is especially hard on mobile devices. The page also has nothing to show until that JavaScript has downloaded and run.
That is why the same guide encourages developers to consider server-side rendering or static rendering over a full rehydration approach. Its definitions are worth keeping straight, because the fixes below use them:
Server-side rendering: rendering the app on the server to send HTML, rather than JavaScript, to the client.
Static rendering: producing a separate HTML file for each URL at build time.
Prerendering: running a client-side app at build time to capture its initial state as static HTML.
Hydration: running client-side scripts to add state and interactivity to server-rendered HTML.
When is client-side rendering fine?
When the page does not need to be found. Dashboards, settings, editors and anything behind a sign-in are never meant to rank or be quoted, so rendering them in the browser costs nothing in search. Most products need server-rendered HTML only for the public surface: the homepage, pricing, features, docs, the blog and any page you would share.
Draw the line by URL, not by component. List the routes a stranger could land on from a search result, an AI answer or a shared link; those need the content and tags in the HTML. Everything else can stay a single-page app.
How do you fix client-side rendering for SEO?
Put public content into the HTML the server sends, either by rendering on each request or by generating pages at build time. Keep client-side rendering for screens behind a login, which never needed to rank. Google recommends server-side rendering, static rendering or hydration, and calls dynamic rendering (serving bots a different version) a workaround, not a recommended solution.
Fix
What it means
Good fit
Server-side rendering
Each request returns finished HTML, then JavaScript hydrates it
Pages whose content changes often, or per request
Static generation
Pages rendered to HTML at build time
Marketing pages, docs, blog
Prerendering marketing routes
Keep the SPA, but render /, /pricing, /blog/* to static HTML at build
An existing Vite SPA with a small public surface
Move marketing pages to a framework
Public pages in Next.js (or similar), the app stays as it is
A product whose app and site are separate anyway
Dynamic rendering
Serve bots a server-rendered copy, users the SPA
Google calls it a workaround and not recommended
In a Next.js App Router project you get this by default: Client Components are prerendered to HTML on the server along with Server Components, and JavaScript then hydrates them. Moving a React SPA to a server-rendering framework is the most complete fix. It is also the route Lovable took for its own builder: it made TanStack Start, with server-side rendering, the default for new projects on May 13, 2026. The guide to indexing AI-built apps covers the per-builder details, and the Lovable SEO guide covers older Lovable projects.
Whatever you choose, re-run the curl test afterwards. The fix is done when your H1, your title and your canonical all appear in the raw HTML of every public page.
To run that comparison on a live page automatically, run the free scan on LaunchScaler. It needs only your URL and no account. Its free checks load the page both ways, raw and rendered in a real browser, flag primary content that only appears after JavaScript runs, and read the title, description, canonical and robots directives from the HTML as served, among 156 checks across 6 of its 7 categories.
Mostly not. Vercel's crawl analysis found that OpenAI's crawlers, ClaudeBot, PerplexityBot, Meta's and ByteDance's crawlers fetch JavaScript files but do not execute them. Gemini, which uses Googlebot's infrastructure, and Applebot do render.
03
Can a React app rank without server-side rendering?
On Google it can, because Google renders JavaScript, though indexing is slower and depends on rendering succeeding. It will be close to invisible to AI crawlers that read only the HTML, and to link-preview bots, unless the content and tags are in the HTML response.
04
How do I check if my content is in the raw HTML?
Run curl -s https://yoursite.com/page and search the output for your H1 or a sentence from the page. If it is missing, crawlers that do not run JavaScript see an empty shell.
05
What is the best fix for client-side rendering SEO?
Render public pages on the server or at build time, with a framework such as Next.js or by prerendering your marketing routes. Keep client-side rendering for signed-in app screens that do not need to rank.
Consent Mode v2 sends ad_storage, analytics_storage, ad_user_data and ad_personalization. Set all four to denied before tags load, then update on consent.