Stagehands assembling a glowing city skyline set piece behind a half raised theatre curtain
Technical SEO

JavaScript SEO: The Practical Guide

JavaScript SEO is the practice of making sure content, links and metadata that depend on JavaScript can still be crawled, rendered and indexed by search engines. It matters because a page can look perfect in a browser while Google receives something close to an empty shell, and nothing in that shell can rank.

We should declare our position early. Luckywebs is a London SEO and web agency, and we build client sites as static HTML on Astro precisely so this class of problem never appears. This guide covers what we check, in the order we check it.

Disclosure: some links on this page are affiliate links. If you sign up through one we may earn a commission at no extra cost to you. We only recommend tools we would genuinely use.

How does Google process JavaScript?

Google processes JavaScript in three phases: crawling, rendering and indexing. Googlebot fetches a URL and parses the raw HTML for links, then queues the page for rendering in a headless Chromium browser. Once rendering completes, Google parses the rendered HTML for links again and uses that rendered HTML to index the page.

The rendering step is the one that catches people out. As of July 2026, Google’s documentation states that a page “may stay on this queue for a few seconds, but it can take longer than that”, and that rendering happens “once Google’s resources allow”. Google renders with an evergreen version of Chromium, so modern JavaScript support is not the risk; the risk is everything that has to go right before your content exists.

Think of it as two waves: raw HTML first, rendered HTML second. If your content, internal links or meta tags only exist after the second wave, every one of them depends on a render pipeline you cannot see and do not control. Static HTML skips that dependency entirely.

What are the most common JavaScript SEO failure modes?

The most common JavaScript SEO failure modes are content that only exists after client-side rendering, JavaScript files blocked by robots.txt, links and metadata that depend on hydration, and infinite scroll without paginated URLs. Each one leaves Google holding an incomplete version of the page, and each one is invisible if you only ever look at the site in a browser.

Content that only exists after client-side rendering

A client-side rendered page sends the browser a near-empty HTML document plus a JavaScript bundle, and the bundle assembles the content. If that bundle fails to execute during Google’s render (a timeout, a script error, a blocked resource), the indexed version of the page is the empty document. The page does not fail loudly; it simply ranks as thin content, because to Google it is.

JavaScript files blocked by robots.txt

Google’s documentation is blunt on this point: Google Search will not render JavaScript from blocked files or on blocked pages (per Google’s JavaScript SEO basics documentation, July 2026). A single careless Disallow: /assets/ or a blocked /_next/ path can stop rendering across an entire site, and it usually arrives via a robots.txt copied from an old project or a staging environment.

Hydration is the step where a JavaScript framework attaches behaviour to HTML in the browser after the page loads. Two things commonly break here. First, navigation built from div or span elements with click handlers: Google discovers links through a elements with an href attribute, so router links without real hrefs are invisible to a crawler. Second, titles, canonicals and robots tags injected client-side: Google can read them once the page renders, but if the render misfires, your directives are simply not there.

Infinite scroll without paginated URLs

Google Search does not interact with your page. It does not scroll, and it does not click a Load More button, so content revealed only by interaction is never seen. Google’s guidance for infinite scroll is to give each content chunk its own persistent, unique URL (an absolute page number such as ?page=12), to link sequentially between those URLs, and to update the address bar with the History API as the user scrolls.

How do you diagnose JavaScript SEO problems?

To diagnose JavaScript SEO problems, compare what a browser shows a user with what Google actually receives and renders. Three checks cover almost every case: the rendered HTML in Search Console’s URL Inspection tool, a diff between raw HTML and the rendered DOM, and your server log files. None of them needs specialist software.

Inspect the rendered HTML in Search Console

URL Inspection is the closest you can get to seeing through Google’s eyes. Inspect the URL, run a live test, then open View Tested Page and read the HTML tab. Do not stop at the screenshot: search the rendered HTML for a sentence of body copy, the title tag and a handful of internal links. If they are missing there, they are missing from the index.

Compare raw HTML with the rendered DOM

Most SEO JavaScript audits come down to one comparison: what the server sends versus what the browser builds. Fetch the raw HTML from a terminal and search it for content you know is on the page:

curl -s https://www.example.co.uk/some-page/ | grep -ci "a distinctive phrase from the page"

If that prints 0 but the phrase is visible in the browser, the content is client-side only. The same test works for title tags, canonicals and internal links. View-source in the browser shows the raw HTML too; the Elements panel in DevTools shows the rendered DOM. Any element that exists in the second but not the first depends on rendering.

Read your server log files

Log files show what crawlers actually fetch rather than what you assume they fetch. Filter for Googlebot and look for three things: whether it requests your JavaScript bundles at all, whether any bundle or API request returns a 404 or 5xx, and whether hashed filenames from an old deployment are still requested after a release. A bundle that 404s for Googlebot means every page that depended on it rendered without its content.

Which rendering strategy should you choose?

Choose the rendering strategy that puts your content into HTML before it reaches the browser. Static site generation and server-side rendering both do this and carry the least JavaScript SEO risk. Client-side rendering carries the most and belongs behind login screens, not on pages that need to rank. Hybrid approaches sit between the two.

Server-side rendering (SSR) builds the HTML on the server for every request. Static site generation (SSG) builds it once at deploy time. Client-side rendering (CSR) sends an empty shell and builds the page in the browser. Hybrid setups serve static or server-rendered HTML and hydrate small interactive components on top.

StrategyHTML the crawler receivesJavaScript SEO riskBest suited to
Static site generation (SSG)Complete, built ahead of timeLowMarketing, service and content sites
Server-side rendering (SSR)Complete, built per requestLow to moderateFrequently changing or personalised content
Hybrid (static plus islands)Complete, with small components hydrated in the browserLow to moderateContent sites with a few dynamic widgets
Client-side rendering (CSR)Near-empty shell, content assembled in the browserHighLogged-in apps and dashboards that do not need to rank

We will be honest about our own bias. Every client site we build is static HTML on Astro, with JavaScript limited to small islands (a form, a gallery, a menu). Our clients work in home improvement trades, law and e-commerce, and not one of their revenue pages needs client-side rendering. That is not a criticism of React or Vue as tools; it is a decision about where the content should live.

How do you test a site for JavaScript SEO issues?

Test a site for JavaScript SEO issues by working through the checklist below before launch, after any framework or dependency upgrade, and whenever organic traffic drops without an obvious cause. Every item takes a few minutes, and each one maps to a failure mode covered earlier in this guide.

  1. Disable JavaScript in the browser and load one URL per template. Confirm the main content is still visible.
  2. Run URL Inspection on one URL per template and read the rendered HTML, not just the screenshot.
  3. Check robots.txt does not block bundle paths such as /assets/, /static/ or /_next/.
  4. View source and confirm the title, meta description, canonical and meta robots exist in the raw HTML.
  5. Confirm every internal navigation element is an a tag with a real, crawlable href.
  6. Check category and listing pages expose unique paginated URLs with sequential links, even if users see infinite scroll.
  7. Confirm error states return a 404 or 410, or carry a noindex, rather than a 200 with an error message.
  8. Check lazy-loaded content loads when it enters the viewport, not when the user interacts.
  9. Repeat the raw-versus-rendered diff after every deployment that touches the framework or build tooling.

JavaScript and SEO: frequently asked questions

Is JavaScript bad for SEO?

JavaScript is not bad for SEO in itself. Google renders JavaScript with an evergreen Chromium and indexes the result. The risk sits in the dependency: when content, links or meta tags only exist after rendering, any render failure silently removes them. Sites that put content in the initial HTML avoid the dependency altogether.

Does Google index JavaScript-generated content?

Yes. As of July 2026, Google’s documentation describes a three-phase process (crawling, rendering, indexing) in which rendered HTML is parsed for links and used to index the page. The practical question is not whether Google can render your page but whether it did, which is why the rendered HTML in URL Inspection matters more than any general reassurance.

How long does Google’s render queue take?

Google’s own wording, current as of July 2026, is that a page may stay on the render queue “for a few seconds, but it can take longer than that”. There is no published maximum. For most sites the delay itself is not the problem; render failures and blocked resources cause far more damage than queue time.

Do meta tags added with JavaScript work?

They can work, because Google indexes from the rendered HTML. They are still the fragile option. A client-side canonical or robots tag only exists if the render succeeds, and conflicting values between raw and rendered HTML invite unpredictable results. Put titles, canonicals and robots directives in the server-delivered HTML wherever you possibly can.

Why does my single-page app show soft 404s in Search Console?

Single-page apps often handle errors in the browser while the server still returns a 200 status code, so Google sees a “not found” message on a supposedly healthy URL. Google’s recommended fixes are to redirect missing content to a URL that genuinely returns a 404, or to add a noindex robots meta tag to the error state.

Do URL fragments (#) work for routing?

No. Google’s documentation says not to use URL fragments to load different content, and notes the old AJAX crawling scheme has been deprecated since 2015. Googlebot cannot reliably resolve fragment URLs. Use the History API so every view has a real URL of its own.

Will Googlebot accept permission prompts, such as camera or location?

No. Google’s guidance is to expect Googlebot to decline permission requests, because features requiring user permission make no sense for a crawler. If your page personalises content by location, serve sensible default content when permission is refused, because that default state is what Googlebot indexes.


Tool note: if you want these checks automated at scale, SE Ranking’s Website Audit can crawl a site with client-side JavaScript rendering switched on, so it sees pages the way a browser does and flags the issues this guide covers. As of July 2026 it offers a 14-day free trial with no credit card needed (per seranking.com, July 2026).

Start Your Free 14-Day Trial

Excellent

Based on 60 reviews

Google

Showing our 12 most recent Google reviews, newest first. No filtering by rating. Read all 60 on Google.