Our services

If you can think it, we can make it brainsoft.

How to get a JavaScript-heavy site indexed properly

Written By: BrainSoft In SEO

You ship a React or Vue app, the page looks perfect in the browser, and then Search Console shows the URL as "Discovered - currently not indexed" for three weeks. Nothing is broken locally. The problem is that the HTML your server returns is mostly an empty div, and the crawler has to run your JavaScript before it sees anything worth indexing.

The fix is to make sure real content exists in the initial HTML response. Below are the steps I run through on every JS-heavy project, in order: diagnose what the crawler sees, fix the cheap things first, then pick a rendering strategy that fits the app.

  1. Check what the server actually returns

Before changing anything, look at the raw response with JavaScript disabled. If the body is a script tag and a root div, that is your whole problem.

curl -s https://example.com/pricing | grep -c "<h1"

A zero here does not mean the page is unindexable, but it means you are relying on the render queue, which is slower and less reliable than plain HTML. Also compare against the rendered DOM in Chrome DevTools to confirm the content is at least reachable.

  1. Make sure the crawler is not blocked before it renders

Rendering needs your JS bundles, your API calls and your fonts. If robots.txt blocks /static/ or /api/, the renderer gets a blank page and reports it as such. Check the URL Inspection tool's "Page resources" list for anything blocked or failing.

  1. Get the metadata into the server response

Title, meta description, canonical and hreflang should not depend on a client-side effect. In a single-page app, at minimum, have the server inject these per route. A small Node or edge function that reads the route and swaps the head tags solves most of it without a full rewrite.

  1. Pick a rendering strategy

Three options, in rough order of effort. Prerendering: run a headless browser at build time or on request and cache the HTML. Fast to add, good for marketing pages and docs, awkward for personalised content. Server-side rendering: render the same components on the server, hydrate on the client. Best result, but you will spend time on data fetching and hydration mismatches. Static generation: pre-render at build, revalidate on a schedule. Great for content that does not change per user.

If the app is behind a login, none of this matters much. If it is a public marketing site with a couple of interactive widgets, prerendering is usually the right call and you can ship it this week. If you are weighing this up across a larger codebase, get in touch and we can look at the routes with you.

  1. Keep links as real anchors

A div with an onClick handler is not a link. Crawlers follow href attributes. Use <a href="/products/42"> and let your router intercept the click. This one change often fixes discovery for whole sections of a site.

  1. Give the crawler a sitemap and sane status codes

Generate the sitemap from your route table so it cannot drift from reality. Make sure unknown routes return a real 404, not a 200 with a client-side "not found" screen. Soft 404s eat crawl budget and confuse indexing reports.

  1. Verify with the rendered HTML, not the browser

After the change, re-run the curl check and confirm the heading, body copy and canonical are present. Then request indexing in Search Console and watch the URL Inspection "View crawled page" output. That is the ground truth, not your local dev server.

Frequently asked questions

Does Google render JavaScript?

Yes, it does, using a headless Chromium renderer. But rendering happens after crawling, on a separate queue, and it can be delayed. Content that only exists after JS runs is indexed later and less reliably than content in the initial HTML.

Is prerendering enough, or do we need SSR?

For public pages with mostly static content, prerendering is usually enough and much cheaper to add. You need SSR when the HTML depends on the request, such as user-specific data or per-request personalisation that must appear in the initial response.

How do I know if my pages are being indexed?

Use the URL Inspection tool in Search Console and check the rendered HTML it shows. A page marked as discovered but not indexed, combined with an empty HTML body from curl, points at a rendering problem rather than a content quality one.


#SEO