React SEO audit: what a crawler sees when the page is JavaScript
The framework is not the problem. Shipping an empty div is.
A client-rendered React app sends the same near-empty HTML for every URL and builds the page in the browser. Google can render JavaScript, but it does so on a delay and a budget, and every other crawler — social previews, AI assistants, smaller search engines — mostly does not.
If the app is a product behind a login, none of this matters. If it has marketing pages, documentation or listings that need to be found, this is what an audit looks at.
What goes wrong on React sites
One title for every route
Without per-route metadata, every URL in the app shares the title and description in index.html. In a search result they are indistinguishable, and most of them will never be indexed at all.
Content that needs JavaScript to exist
The first response is a shell. Everything a crawler is asked to judge arrives later, if it arrives. Server-side rendering or prerendering for public routes is the only reliable answer.
Routes a crawler can't follow
Navigation built on onClick handlers rather than anchor elements is invisible to a crawler. If there is no href, there is no link, and the page behind it is unreachable.
Hash routes
URLs like /#/products/42 are one URL as far as a search engine is concerned. Anything built that way cannot rank as separate pages.
No sitemap, because there are no files
A single-page app has no natural list of URLs. Without a generated sitemap, discovery depends entirely on internal links a crawler can follow — which, given the point above, are often missing too.
Soft 404s on every unknown path
A client-rendered app usually answers 200 for anything, then renders "not found" in the browser. Search engines call that a soft 404, and a site that produces a lot of them gets crawled less carefully everywhere else.
Hydration cost before anything is usable
The bundle downloads, parses and hydrates before the page responds to a tap. That shows up as poor Interaction to Next Paint on exactly the mid-range phones most visitors use, and no amount of on-page work compensates for it.
What an AuditOpti crawl looks for
- What the server returns before JavaScript runs, per URL
- Per-route titles, descriptions and canonicals
- Whether navigation uses real links a crawler can follow
- The sitemap against the routes the app actually serves
- Response codes for deep links — a real 404 rather than a 200 shell
- Core Web Vitals on mobile, where hydration cost is most visible
Check part of it right now, free
These read a live page and tell you what a search engine sees. No signup, no email.
SEO score checker
Score one page against the checks that actually move rankings.
Meta tag checker
Every tag in the head of your page, read back to you the way a crawler sees it.
XML sitemap checker
Find your sitemap, prove it parses, and see what it is actually telling Google.
The issues behind this
Each has a full entry in the issue library: what it is, what it costs a business, and step-by-step fixes for WordPress, Shopify, Webflow and custom builds.
Missing title tag
A page has no title, so search results show a guess.
Thin content
The page has too little text to be useful.
Missing XML sitemap
No sitemap to tell search engines what exists.
Orphan page
No other page on the site links to it.
Questions
Related
Crawl the app and see exactly which routes arrive empty
The free audit crawls the site, groups every finding, and returns the five things worth fixing this month in plain English. No card, no call.
Run a free audit