
A React SPA SEO audit checks public routes, their responses, rendered content and discovery links. Test more than the homepage: internal navigation can work while a direct product visit fails.
Download the five-route worksheet, illustrative completed matrix and practice lab. The lab uses plain browser JavaScript and a local Python server, not React. It models common failures without claiming Googlebot observations or production results. For background, read the JavaScript SEO guide.
Key takeaways
- Test five route states: valid, unknown, removed, filtered and temporarily unavailable.
- Record the document response separately from API responses and the rendered page.
- A browser test is implementation evidence; Search Console provides a separate Google-specific view.
- Download the audit worksheet and practice lab, then verify fixes on direct visits and internal navigation.
- What do you need before a React SPA SEO audit?
- React SPA SEO audit: choose five route states
- Step 1: inspect the document response
- Step 2: compare the rendered content and metadata
- Step 3: check links and addressable routes
- Step 4: distinguish soft 404s from temporary failures
- Practice with the downloadable SPA route lab
- Step 5: inspect Google evidence and hand off the fix
- Frequently asked questions
- Sources and further reading
What do you need before a React SPA SEO audit?
Collect representative URLs and agree which should be searchable. Use a fresh public browser session, developer tools and Search Console access when available. Record the deployment, test date and any staging differences.
Ask who controls hosting fallbacks, route handling and failed data requests. Intentional login restrictions or staging noindex directives are not automatically defects. If you use server-rendered React, the response comparisons still help, although the implementation remedy may differ; see the Next.js App Router guide.
React SPA SEO audit: choose five route states
Choose a valid page, unknown slug, removed item, filtered view and temporary data failure. Define the expected result before testing.
| State | Hypothetical route | Question |
|---|---|---|
| Valid | /products/tea-set/ | Does a direct visit show the intended product? |
| Unknown | /products/not-a-product/ | Does a missing URL have an appropriate error state? |
| Removed | /products/old-mug/ | Is it removed, retained as useful content, or genuinely replaced? |
| Filtered | /collection/?color=red | Does its canonical/indexing policy match the approved intent? |
| Data failure | /products/api-down/ | Is a temporary problem being mistaken for permanent removal? |
Use real examples from your application. A useful out-of-stock product may remain public, while a distinct filtered category may deserve indexing. Test each route through an address-bar visit, internal navigation and reload. These paths can expose different hosting behaviour or stale client state.
Step 1: inspect the document response
Reload with the Network panel open, preserving requests. Select the document, record its status and redirect chain, and inspect its Response tab for initial HTML. Keep API statuses separate: a 404 API response does not turn the document into a 404.
Chrome's Network documentation explains headers and responses. Record the exact URL, cache/login state and failed dependencies. Confirm with a GET if the host handles HEAD differently.
Under Response Headers, also inspect X-Robots-Tag; an indexing restriction can exist there even when the DOM has no robots meta tag. Check both layers. A 200 response permits processing but guarantees no indexing, as Google's status guidance explains. For a failure already found in crawl logs, retain its timestamp for correlation.
Step 2: compare the rendered content and metadata
Once loading finishes, compare visible content and head metadata with the initial response. An empty shell establishes a JavaScript dependency, not proof that Google cannot index it.
document.title
document.querySelector('h1')?.textContent
[...document.querySelectorAll('link[rel="canonical"]')]
.map(el => el.href)
[...document.querySelectorAll('meta[name="robots"]')]
.map(el => el.content)
Check product details as well as headings. Inspect title, canonical and robots state after navigation and reload; stale values may describe the previous destination. Multiple canonicals, generic homepage targets or missing content need evidence-led investigation. Use the canonical guide to distinguish intentional consolidation from a faulty route.
Step 3: check links and addressable routes
Inspect rendered navigation for meaningful anchor href values, then open destinations independently. A router component's name does not prove its HTML output is a crawlable link.
Google's link guidance supports ordinary anchors. JavaScript can enhance them; clickable buttons or divs should not be the sole discovery path to a public page.
<!-- Expected output for a public route -->
<a href="/products/tea-set/">Tea set</a>
Review fragment-based content routing separately from section anchors. A searchable destination needs an addressable route, useful content and relevant return links. The internal-linking guide covers that context.
Step 4: distinguish soft 404s from temporary failures
Separate permanent absence from temporary failure. A not-found message behind a 200 fallback can create a soft-404 problem; an existing product with an unavailable API requires a different diagnosis.
Return an appropriate document status where possible. Google's SPA guidance also permits redirecting an error state to a real 404 URL or inserting noindex through JavaScript. Neither a client message nor an API status changes the document response retroactively.
Do not put noindex in valid pages' initial HTML and depend on JavaScript to remove it. Check recovery during navigation too: an error directive must not persist on a valid destination.
For outages, discuss retries, cached content and server behaviour. Avoid blanket noindex rules for every failed fetch. For genuine replacements, assess a relevant redirect; unrelated homepage redirects seldom answer the original request.
Practice with the downloadable SPA route lab
The local lab intentionally contains failures. Extract the ZIP, follow its README and run python server.py with Python 3. Open the supplied localhost URL. The server binds to your computer and needs no external packages, credentials or analytics.
| Route state | Lab document status | Rendered result | Finding |
|---|---|---|---|
| Valid product | 200 | Product content and its own metadata | Capture this as the working reference. |
| Unknown slug | 200 | Not-found message without noindex | Soft-404 risk requiring a defined correction. |
| Removed item | 410 | Removal message | A deliberately removed route; not a successful product. |
| Filtered collection | 200 | Filtered list with base-collection canonical | Check that the duplicate policy is intentional. |
| Data request fails | 200 | Temporary error; API returns 503 | Document and API statuses differ. |
Use the lab to practice distinguishing document and API responses, then inspect your actual React app. Its completed matrix describes these synthetic states only. Leave Google inspection marked “not tested” until an eligible property's evidence is available.
Step 5: inspect Google evidence and hand off the fix
Use Search Console URL Inspection to compare stored information with a live test where available. Record dates, rendered content and resource failures. A successful live test guarantees neither indexing nor ranking.
For developer handoff, include URL, visit method, response, rendered outcome, expected policy, owner and acceptance check. Attach a screenshot or excerpt. “Direct and internal visits display the product with one correct canonical” is testable; “improve SEO” is not.
Repeat the matrix after deployment, including back/forward navigation when it affects metadata. Distinguish a verified release from a pending Google recrawl. For implementation help, see the specialist selection guide and technical SEO service.
Frequently asked questions
Can Google index a client-rendered React page?
Google can render JavaScript. Whether a particular destination works depends on its content and dependencies. Browser checks and Google inspection provide different evidence.
Does every SPA need server rendering?
No. Choose architecture from demonstrated failures and user needs. Routing, metadata and error states still require checks after switching rendering methods.
Is a 404 API response enough?
No. Inspect the document and rendered outcome separately, then implement a suitable missing-page strategy.
Is the completed worksheet a client audit?
No. It records the practice lab. The blank version is for your application and has no prefilled Google or ranking claims.
Sources and further reading
Need an implementation audit for a React or Next.js website? Send the site URL and one route that is not behaving as expected.
Get in touch