JavaScript SEO: Get React and Next.js Sites Indexed

TL;DR: JavaScript SEO makes sure Google can see content your site builds with JavaScript. Google reads your raw HTML first and renders the page later, in a separate queue. If a React or Next.js site only assembles its content in the browser, Google can index an empty shell for days, or never. Server-render your money pages, then test what Googlebot really sees.

A development team reviewing code together around a table of laptops
94%of body text missing before rendering on a React SPA
24 daysmedian wait to index a client-rendered page on a new domain
4checks that show what Googlebot actually sees
6fixes to hand your developer

A Malaysian SME pays RM 25,000 for a beautiful React site. Six months later it has almost no organic traffic. The agency blames the content, the developer blames the algorithm, and everyone runs another keyword audit. Nobody opens view-source, where the page turns out to be one empty <div id="root"> and a script tag.

That is a rendering problem, not a content problem, and it is what JavaScript SEO exists to solve. This guide covers Google's two-wave indexing, how to test what Googlebot sees on your own pages, which rendering mode belongs on which page type, and the fix list to hand a developer. It sits under our SEO services because on framework sites this is usually what has to be fixed before anything else can rank.

The short video below is Google's own explanation of how Search handles JavaScript sites. Watch the part where rendering is described as separate from the crawl, because everything here follows from that one design decision.

How Google Search indexes JavaScript sites - JavaScript SEO

Source video: Watch on YouTube

1. What is JavaScript SEO, and why do React sites go missing?

Quick Answer: JavaScript SEO is the practice of making JavaScript-built content crawlable and indexable. React, Vue and Angular apps often send an empty HTML shell and fill it in afterwards. Google can render that shell, but later and not always, so pages that look perfect to you can reach the index with no content.

Every other SEO problem is about what is on the page. This one is about whether the page exists yet at the moment Google looks. That matters, because the standard advice for pages not getting indexed by Google starts with robots.txt, canonicals and thin content. On a single-page app, all three can be perfect and the page still indexes empty.

The mechanism is simple once you see it. A traditional server sends finished HTML. A client-rendered app sends a near-empty document plus a script bundle, and the content only appears after that bundle downloads and runs. Your browser does this in under a second on office wifi. Google does it on its own schedule.

Two colleagues discussing a project plan at a desk
  • Framework choice is not the problem. React, Vue and Angular can all rank. How you render them decides whether they do.
  • The symptom is invisible in a browser. The page looks complete to a human, which is why these issues survive months of reviews.
  • New domains suffer most. An established site gets rendered quickly; a brand-new Malaysian SME site waits far longer in the queue.

Google's JavaScript SEO basics documentation is explicit that pages are queued for rendering and processed when resources allow. Read that as eventual rendering, not immediate rendering, and the risk becomes obvious.

Key takeaway: JavaScript SEO is not about which framework you chose. It is about whether your content exists in the first HTML response or only after a script runs.

Suspect your site renders empty for Google?

We run a rendering check in every technical audit, before anyone writes a new page.

See how ZenWeb runs SEO for Malaysian businesses →

2. Two-wave indexing: what Google does with your JavaScript

Quick Answer: Google crawls in two waves. Wave one fetches the raw HTML and indexes what is in it. Wave two queues the page for rendering, runs the JavaScript in a headless browser, and re-indexes the result. Between the waves your page can sit in the index with a title, a URL and nothing else.

The rendering queue is the part that surprises people. Crawling is cheap; running a browser is not. So Google separates them, which is also why crawl budget behaves differently on a JavaScript site. A fetch that costs almost nothing on a WordPress page becomes an expensive render on a React page, and Google prioritises accordingly.

A person at a desk working through technical documentation

Three consequences follow directly, and they explain most of the confusing symptoms owners report:

  • Delay, not denial. Content usually indexes eventually. On a low-authority new site, "eventually" can be weeks after publishing, which is fatal for anything time-sensitive.
  • Partial indexing. Google may index the wave-one shell and never re-crawl often enough to refresh it, leaving an empty version live in Search.
  • Links found late. If your internal links only exist after the script runs, wave one finds none, and discovery of the rest of the site stalls. Our explainer on how Google crawls and indexes a website covers why discovery order matters.

Google sets out the same sequence in its guide to how Search works: crawl, render, index, with rendering as its own step. Accept that ordering and the fix stops being clever. Put the content in wave one.

Key takeaway: Rendering is a separate, lower-priority step. Anything Google needs to know in week one belongs in the raw HTML, not in the bundle.

3. How to test what Googlebot actually sees on your page

Quick Answer: Compare two views of the same URL: the raw HTML in view-source and the rendered HTML in Search Console. If your headline and body copy appear in the browser but not in view-source, the content depends on rendering. That gap, measured per template, is the whole diagnosis.

You do not need a crawler licence for this. Four checks, ten minutes, and you will know more about your site's JavaScript SEO than most audits report. Start in Google Search Console, which shows Google's own rendered copy rather than a third-party simulation.

  1. Open view-source on a money page. Put view-source: before the URL and search for a distinctive sentence. Missing means client-rendered.
  2. Run URL Inspection in Search Console. Inspect the URL, choose Test live URL, then open the tested page. Google's rendered source documentation explains how to read the HTML tab and the screenshot together.
  3. Read the console output. The same panel lists console messages and blocked resources. One failed API call can empty the whole page for Googlebot.
  4. Crawl with rendering off, then on. A desktop crawler such as Screaming Frog runs both modes and diffs word and link counts per URL. Biggest gaps go to the top of the list.
A developer inspecting a page in a browser on a laptop

Two habits stop most false alarms. Test a page type, not one page, because templates fail together. And test a page you have not visited recently, since your own cache hides the problem.

Key takeaway: The diagnosis is a diff, not an opinion. Raw HTML against rendered HTML on the same URL settles the question in minutes.

4. How much of your page is missing from the raw HTML?

Quick Answer: In ZenWeb's technical audits of Malaysian sites, pure client-side apps deliver almost none of their body text in the first HTML response, while server-rendered and static builds deliver nearly all of it. Half-configured Next.js sites sit in the middle, and that is the most commonly misdiagnosed case.

The chart below is the diff from Section 3, run across the build types we see most often on Malaysian SME sites. It measures body text only, so navigation and boilerplate are excluded. Filter-heavy stores are a separate case, covered in our guide to faceted navigation and filter page crawl bloat.

Share of body text missing from the raw HTML response, by build type
Bar chart table showing, for eight common website build types, the percentage of indexable body text absent from the raw HTML response and appearing only after JavaScript renders, based on ZenWeb technical audits of Malaysian sites.
Build typeMissing before renderingShare
React SPA, no server rendering
94%
Vue SPA, no server rendering
91%
Angular SPA, no server rendering
88%
Next.js with client-side data fetching
47%
Headless CMS front end, partial SSR
39%
WordPress with JS tabs and accordions
22%
Next.js or Nuxt, SSR or SSG
5%
Static HTML or Astro
2%

Source: Based on ZenWeb's client sample of 500+ Malaysian SME accounts, raw-versus-rendered body text audits, 2024–2026. Body text only.

A laptop screen showing an analytics graph

The fourth row costs Malaysian businesses the most money. A Next.js build feels safe because the framework supports server rendering, but if the developer fetched the content in the browser instead, roughly half the page still waits for wave two.

Key takeaway: "We built it in Next.js" is not the same as "it is server-rendered". Measure the gap per template before you trust the framework name.

5. CSR, SSR, SSG or ISR: which rendering mode for which page?

Quick Answer: Use static generation for pages that rarely change, incremental regeneration for catalogues and blogs, and server rendering for anything personalised that still needs to rank. Keep client-side rendering for logged-in dashboards and interactive widgets. The rule is short: if a page should rank, it must not be client-rendered.

Most teams pick one mode for the whole site, which is where the argument starts. You do not have to. Modern frameworks let you set the mode per route, so this becomes a page-type decision that maps onto your site structure and page hierarchy.

A person planning page templates on printed sheets
Rendering modes compared for indexing and page fit
Comparison table of four rendering modes, showing what the crawler receives first, the page types each mode suits, and the indexing risk for a Malaysian SME site.
ModeWhat the crawler gets firstBest forIndexing risk
Static generation (SSG)Complete HTML, built ahead of timeService pages, landing pages, about, pricingLowest
Incremental regeneration (ISR)Complete HTML, refreshed on a scheduleBlogs, product catalogues, listing pagesLow
Server rendering (SSR)Complete HTML, built per requestStock-aware product pages, location pages, indexable search resultsLow, but slow servers hurt
Client rendering (CSR)An empty shell plus a script bundleLogged-in dashboards, carts, configuratorsHighest

Source: Compiled from Google Search Central rendering guidance and ZenWeb implementation reviews on Malaysian client builds, 2024–2026. Darker cells indicate greater indexing risk.

One workaround deserves a warning. Dynamic rendering, where you serve a prerendered copy to bots only, was always a stopgap, and Google now treats it as a workaround rather than a recommended solution. It buys time on a legacy app and is the wrong answer for a site you are building this year.

Key takeaway: Choose the rendering mode per route, not per project. Anything with a keyword behind it gets SSG, ISR or SSR; client rendering is for pages behind a login.

Not sure which pages need server rendering?

Our technical retainers include a route-by-route rendering plan your developer can implement directly.

Compare our SEO packages and pricing →

6. How long does JavaScript content take to get indexed?

Quick Answer: Server-rendered pages on the Malaysian sites we track are typically indexed within a couple of days. Client-rendered pages on a new domain routinely take weeks, and some never index their full content. The gap has narrowed since 2023 but has not closed, and it is widest exactly where new sites live.

This number decides whether a rendering problem is urgent or academic. If your pages are evergreen, a two-week delay is survivable. If you publish offers, events or stock, it is not. Sites at the far end of this table usually appear first as discovered but not indexed in Search Console.

Median days from publish to full content indexed, 2023–2026
Time-series table showing the median number of days from publishing to full content being indexed, for four rendering and domain-authority combinations, each year from 2023 to 2026, across ZenWeb-tracked Malaysian client sites.
Page setup2023202420252026 (Jan–Aug)
Server-rendered, established domain3 days2 days2 days2 days
Server-rendered, new domain11 days9 days7 days6 days
Client-rendered, established domain14 days12 days9 days8 days
Client-rendered, new domain38 days33 days27 days24 days
A calendar and notebook on a desk beside a laptop

Source: From ZenWeb client tracking across 12 industries, Malaysia, 2023–2026. Median across pages that did index; pages never reaching full-content indexing are excluded, so the real lag is worse. 2026 covers January to August.

Note what the footnote removes. Pages that never indexed their content at all are outside these medians, and on client-rendered new domains those are the ones that quietly sink a launch. Many sit as crawled but not indexed for months.

Key takeaway: A new Malaysian site that renders in the browser waits weeks for content Google could have had on day two. Rendering delay is a launch risk, not a technicality.

7. The JavaScript SEO mistakes we find most on Malaysian sites

Quick Answer: The recurring faults are router links that are not real anchor tags, titles and canonicals written after load, content hidden behind a click, blocked script files, and infinite scroll with no crawlable pages behind it. All are invisible in a browser and all are cheap to fix at template level.

These are not exotic edge cases. They are the same handful of patterns, repeated across builds, usually because nobody owned JavaScript SEO as a requirement. Because they are template faults, one change repairs hundreds of URLs at once.

  • Navigation that is not a link. A div with a click handler moves a user but gives wave one nothing to follow. Internal links must be real <a href> elements.
  • Titles and canonicals set client-side. If the framework writes them after load, Google may index the template defaults. That is a common route to canonical tag mistakes and to Google indexing the wrong URL.
  • Blocked JavaScript and CSS. Disallowing a bundle path stops rendering outright, so rule out robots.txt blocking Google before hunting a rendering bug.
  • Content behind interaction. Tabs, read-more toggles and modals that only fetch on click are not indexed. Load the content, then hide it visually.
  • Infinite scroll with no paginated URLs. Listings need real, linkable pages underneath, the same discipline that makes e-commerce SEO in Malaysia work at catalogue scale.
  • Hydration errors nobody reads. A mismatch between server and client output can blank a section. Google's guide to fixing search-related JavaScript problems is the checklist.
A marketer working through a checklist at an office desk

There is a Malaysian wrinkle worth naming. Much SME traffic here arrives on mid-range Android phones over mobile data, so a heavy bundle that renders fine on a laptop can time out for real customers even when Google eventually copes. That is why rendering work usually shows up in Core Web Vitals at the same time. Marketplace sellers face the mirror image, where the platform controls rendering entirely, which we cover in Shopee and Lazada listing SEO.

Key takeaway: A handful of template-level faults cause most JavaScript SEO failures. Real anchor tags and server-set metadata alone fix the majority.

8. What it costs to fix rendering before launch versus after

Quick Answer: Choosing server rendering during architecture costs nothing. Retrofitting it onto a live single-page app costs developer weeks and a period of unstable rankings. A front-end rebuild costs the most and carries migration risk. Doing nothing is the only option with an unbounded cost.

Owners usually ask for this comparison after the site is live, so the honest version includes the option most quotes leave out. The table models a typical Malaysian SME site of roughly 60 to 200 pages.

Modelled cost of each rendering fix path (Malaysian SME site, 60–200 pages)
Grouped table modelling five rendering fix paths for a Malaysian SME website, showing when each is decided, the developer effort required, the direct cost in ringgit, and the effect on organic traffic.
Fix pathDecided whenDeveloper effortDirect costEffect on organic traffic
Pick SSG or SSR at architecture stageBefore any codeNone, it is a config choiceRM0Indexed from launch
Move data fetching server-side on key routesLive site, framework supports it1–3 weeksRM3,000–9,000Recovers over 4–8 weeks
Add prerendering as a stopgapLive site, legacy app3–10 daysRM1,500–4,000 plus monthly feesPartial, needs ongoing upkeep
Rebuild the front end on a rendering frameworkLive site, no server rendering possible6–14 weeksRM15,000–60,000Dip, then step change, if URLs are preserved
Do nothing and keep buying adsBy defaultNoneWhole ad budget, every monthStays near zero indefinitely
A person reviewing cost figures on printed reports

Source: Illustrative model based on ZenWeb scoping for Malaysian SME front-end work, 2024–2026. Ranges vary by page count and integrations. Not a quote.

Read the first and last rows together. The same decision costs nothing at the wireframe stage and can cost a rebuild eighteen months later, which is why technical SEO belongs in the build brief. If you are already mid-rebuild, our notes on traffic crashes after a site migration cover what to protect.

Key takeaway: Rendering is free to get right and expensive to retrofit. Put it in the specification before the first sprint, not in an audit after launch.

Building on React or Next.js this year?

We write rendering and indexing requirements into the build brief so the fix never becomes a rebuild.

See how ZenWeb handles web development →

9. The JavaScript SEO fix list to hand your developer

Quick Answer: Give the developer a route list with a rendering mode against each entry, then fix links, metadata, blocked resources and interaction-gated content in that order. Re-test with URL Inspection after each change. Six items, written as requirements rather than complaints, usually closes the gap.

Developers are rarely the problem. In most cases nobody told them indexing was a requirement, so they optimised for what they were measured on. Hand them this list and most of it is a day's work per template.

  1. Assign a rendering mode to every route. One table: URL pattern, mode, reason. Money pages get SSG, ISR or SSR; nothing indexable stays client-rendered.
  2. Make every internal link a real anchor. Replace click handlers with <a href> elements pointing at real URLs, and keep the router on top of them.
  3. Move titles, descriptions and canonicals server-side. They must appear in view-source, unique per page, before any script runs.
  4. Unblock scripts, styles and APIs in robots.txt. Confirm with the rendered screenshot, not by reading the file.
  5. Load indexable content without interaction. Tabs and read-more panels ship their content in the HTML and hide it with CSS, never fetch it on click.
  6. Serve real URLs behind listings and render schema server-side. Paginate infinite scroll into crawlable pages, and output JSON-LD on the server so it survives for Google and AI search engines.
Server racks in a data centre, where a server-rendered page is built

Two habits keep the fix in place. Preserve URLs whenever a template changes, and where a URL must move, use proper 301 redirects rather than JavaScript redirects. Meanwhile keep the SEO work that never depended on rendering moving, such as seeding buying questions in your Google Business Profile Q&A, which earns leads while the developer works.

Key takeaway: Write the fixes as build requirements with a route table attached. Developers deliver what is specified, and indexing has usually never been specified.

10. Conclusion: put the content in the first response

JavaScript SEO reduces to one sentence. Google reads your raw HTML immediately and renders your JavaScript later, so anything that matters for ranking should already be in the first response. React, Next.js, Vue and Nuxt all support that. The failure is almost never the framework; it is that nobody made indexing a requirement before the build started.

Start with the diff from Section 3 on your three most valuable templates. If the content is missing from view-source, you have your priority, and the route table in Section 9 is your brief. Once rendering is sorted, ordinary technical SEO and content finally have something to stand on. If you would rather hand it to a team that does this weekly, that is what our SEO service is for, and the rest of what we do is at ZenWeb.

Is your React or Next.js site invisible to Google?

Book a free rendering check. We compare raw and rendered HTML across your key templates, show you which pages Google is indexing empty, and give you the route-by-route fix list to hand your developer.

Book my free rendering check →
A business owner smiling while working on a laptop in a bright office

11. Frequently Asked Questions

1. Can Google index a React website?

Yes, but not reliably if the site is purely client-rendered. Google crawls the raw HTML first and renders JavaScript later in a separate queue, so a React page that builds its content in the browser can be indexed as an empty shell for days or weeks. Server-rendering or statically generating the pages you want to rank removes the risk.

2. Is Next.js better than React for SEO?

Next.js is easier to get right because it supports static generation, incremental regeneration and server rendering out of the box. It is not automatically better. A Next.js site whose developer fetches page content in the browser has the same problem as a plain React app, so check view-source before assuming the framework solved it.

3. How do I check if Google can see my JavaScript content?

Open the page with the view-source: prefix and search for a sentence from your body copy. Then inspect the same URL in Google Search Console, run Test live URL, and read the rendered HTML tab and screenshot. If the text appears in the rendered view but not in view-source, your content depends on rendering.

4. Does client-side rendering hurt rankings even if pages get indexed?

Usually yes, indirectly. Indexing arrives later, so fresh pages compete late. Heavy bundles slow loading on mid-range Android phones, which carry most Malaysian mobile traffic, and that shows up in Core Web Vitals. Internal links discovered only after rendering also spread authority around the site more slowly.

5. Should I use dynamic rendering to serve HTML to Googlebot?

Only as a temporary measure on a legacy application. Google now describes dynamic rendering as a workaround rather than a recommended solution, and it adds a separate system to maintain and monitor. For any site being built or rebuilt now, server rendering or static generation is the correct answer.

6. How long does it take to see results after fixing rendering?

On the Malaysian sites we track, indexing of previously empty pages usually improves within two to four weeks of the fix going live, with ranking movement over the following one to two months. Speed depends on how often Google already crawls the domain and how many templates changed at once.

A team discussing technical questions around a table

Meowketing Specialist

Online

Today

Meow! 👋

We are Official Google Partner,
Ask us anything about Marketing!