Skip to main content
Practical guide

JavaScript SEO Problems and Solutions: Technical Guide 2026

When a Modern Website Becomes an SEO Black Hole

There is a scenario that repeats itself across technical SEO audits: a company spends months building a modern web application with React, Angular or Vue, launches it with confidence, and weeks later discovers that Google has not indexed most of the content. The pages load correctly in the browser. Users can navigate them. But in search results, they simply do not exist. Organic traffic never arrives, and no one understands why.

This is not an edge case. It is the direct consequence of building a site that relies on JavaScript to generate its main content without accounting for the implications for crawling and indexation. The problem is not JavaScript itself, which is a legitimate and powerful technology. The problem is assuming that search engines will process it the same way as static HTML, when the reality is fundamentally different.

A single data point illustrates the scale of the challenge: according to Conductor Academy, rendering JavaScript pages is approximately 100 times more computationally expensive for search engines than processing equivalent static HTML. That difference is not a minor technical footnote. It determines how many pages Google can crawl on your site, when your content will appear in results, and ultimately how much organic traffic your site captures.

This guide maps the ten primary JavaScript SEO problems and their corresponding solutions. For a broader grounding in technical SEO as a discipline, see our complete technical SEO guide.


How Googlebot Handles JavaScript: The Two-Phase Model

To understand why JavaScript creates SEO problems, it is necessary to understand how Googlebot processes it, because its behavior is radically different from a browser.

When a user visits a page, the browser downloads the HTML, executes JavaScript immediately, and renders the resulting content in a fraction of a second. Everything happens in a single continuous process. The result is the complete, interactive page.

Googlebot operates in two completely separate phases. In the first phase, the crawler downloads the initial HTML of the URL and adds it to Google’s index exactly as it is at that moment. If that HTML is an empty shell with only <div> tags and references to JS files, that is all Google processes in the first phase. In the second phase, Googlebot queues the page for rendering with Chromium, executing the JavaScript and processing the final content. This second phase happens in a separate queue and may be delayed by hours, days or weeks.

“Server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript.” — Google Search Central

This two-phase model creates an indexation gap with direct consequences for rankings. Content that only exists after executing JavaScript is not available to Google until the second-phase rendering completes. For sites with frequently changing content or new pages that need to be indexed quickly, this delay is a critical problem.


The Ten Core JavaScript SEO Problems

1. Deferred Rendering Queue

The central issue of JavaScript SEO is the separation between the moment Googlebot downloads a URL and the moment it executes its JavaScript. This gap exists because JS rendering consumes far more computational resources than HTML processing, and Google manages them in separate queues with different priorities.

The practical impact is that dynamically generated content may take days to appear in Google’s index. For news sites, stores with dynamic catalogs, or platforms that publish content frequently, this delay has a direct cost in visibility.

The most effective solution is ensuring that all SEO-critical content — including body text, headings, metadata, and internal links — is present in the initial HTML returned by the server. This eliminates the dependency on JavaScript rendering for content to be indexable.

2. Hash-Based URL Fragments Are Not Indexable

Single Page Applications (SPAs) using hash-based routing generate URLs like mysite.com/#/product/123. This format has a fundamental problem: the # fragment and everything after it is processed only by the client-side browser and is never sent to the server. Googlebot cannot crawl or distinguish between these URLs.

The result is that the entire site appears to Google as a single URL: mysite.com. All the pages, categories and products a user can navigate are invisible to the search engine.

The solution is migrating to the History API, which allows SPAs to use clean URLs like mysite.com/product/123. React Router, Vue Router and Angular Router have implemented the History API by default for years. If a SPA still uses hash routing, it represents a first-order technical SEO debt.

3. Soft 404 Errors in Single Page Applications

A specific problem with poorly configured SPAs is the “soft 404.” This occurs when a user reaches a non-existent URL in the SPA, the application renders an error page (“Not Found”), but the server returns HTTP 200 OK instead of the correct 404.

Google sees the 200 status code and assumes the page contains valid content. It proceeds to index it. The result is indexed error pages that compete negatively with real content and waste crawl budget.

The fix requires implementing server-side logic to return the correct HTTP codes: 404 for missing pages, 301 for permanent redirects, 410 for permanently deleted pages. In SSR architectures this is straightforward. In pure CSR with SPA, it requires a server layer — such as a service worker or reverse proxy — to handle status codes.

4. Scroll-Dependent Lazy Loading

Lazy loading is a legitimate and recommended technique for improving performance, but if implemented incorrectly it can make important content invisible to Googlebot.

The specific problem is that Googlebot does not scroll during page rendering. Lazy loading implementations that depend on scroll events to load content — such as images, text sections or product lists — will never expose that content to the crawler.

Google explicitly documents how to implement lazy loading in an SEO-compatible way. The official recommendation is to use the Intersection Observer API, which detects when an element enters the viewport regardless of how it got there. Additionally, the native loading="lazy" attribute on <img> tags is safe for SEO and supported by all modern browsers.

What to avoid: lazy loading via JavaScript listeners on the document’s scroll event, since Googlebot never fires that event.

5. Infinite Scroll Without Persistent URLs

Sites with infinite scroll that load additional content when users reach the bottom of the page have a clear SEO problem: if the additional content does not have its own indexable URL, Googlebot cannot access or index it, even though it is visible to users.

Google’s recommended solution combines two elements: first, each “page” of paginated content must have its own accessible URL (for example, /blog/?page=2, /blog/?page=3); second, implement a conventional HTML pagination alongside the infinite scroll, accessible via <a> tags in the HTML, that allows crawlers to follow all content. Infinite scroll can coexist with this structure for users while crawlers follow the conventional pagination links.

6. JavaScript Resources Blocked in robots.txt

A classic but still common mistake is blocking critical JavaScript files in the robots.txt file. When Googlebot cannot access the JS files required to render a page, the result is that it sees only the empty HTML skeleton — exactly as if JavaScript had not been executed at all.

This problem is particularly deceptive because the site works perfectly for users (their browser loads the JS files directly, bypassing robots.txt) but is invisible to crawlers.

The diagnosis is straightforward: the URL Inspection Tool in Google Search Console allows comparison of how Google sees a URL versus how the browser sees it. If there are significant differences in visible content, blocked JS resources are a prime suspect. Screaming Frog with JavaScript rendering enabled also identifies these discrepancies systematically across an entire site.

7. JavaScript-Injected Metadata and Canonicals

When the title tag, meta description, canonical tag or other SEO meta tags are injected exclusively via JavaScript, there is a risk that Googlebot processes the unrendered version and uses incorrect or empty values.

Aleyda Solís, International SEO Consultant at Orainti, has documented this pattern across multiple audits: “Clients using JavaScript for metadata and navigation elements experienced crawling, indexing, and speed performance issues that improved significantly after optimization.”

The correct practice is to include all critical SEO metadata directly in the HTML returned by the server. In React, this means using libraries like react-helmet-async or, better yet, SSR frameworks like Next.js that generate metadata server-side. Client-side JavaScript-injected metadata is an SEO anti-pattern that should be eliminated.

8. Crawl Budget Exhaustion

Crawl budget is the number of URLs Googlebot is willing to crawl on a site during a given period. For small sites, it is rarely a limiting factor. For enterprise sites with thousands or millions of pages, it is critical.

JavaScript intensifies the crawl budget problem in several ways. Each page requiring JS rendering consumes more crawler resources than an equivalent static HTML page. JavaScript applications also generate additional requests (fetch, XHR, WebSockets) that Googlebot must evaluate, as well as large JS bundles that must be downloaded and executed.

The practical result is that Googlebot can crawl significantly fewer pages per session on JS-intensive sites compared to equivalent static HTML sites. For enterprise sites, this translates to portions of the catalog remaining unindexed. For a deeper treatment of this topic, see our crawl budget optimization guide.

9. Incompatibility with Third-Party Crawlers

Google is the most sophisticated search engine at processing JavaScript, but many other crawlers that matter for businesses cannot execute JS at all.

Social media crawlers — including Facebook (Open Graph), LinkedIn and Twitter/X — do not execute JavaScript. This means that sites with pure Client-Side Rendering show blank or generic preview cards when users share URLs on these platforms. 100% of social previews on a pure CSR site are affected.

Bing also processes JavaScript with significant limitations compared to Google, which can affect rankings in markets where Bing holds meaningful share — roughly 8-9% in the United States, for instance.

The solution that eliminates this problem for all crawlers is implementing SSR or pre-rendering, ensuring every URL returns complete HTML regardless of which crawler accesses it.

10. Rehydration Penalty and Time to Interactive

Server-Side Rendering resolves indexation problems, but introduces a new risk if not implemented correctly: the rehydration penalty.

In SSR, the server generates the complete HTML and sends it to the browser, which can render it immediately (improving LCP, Largest Contentful Paint). However, the page is not interactive until the client-side JavaScript is downloaded, parsed, executed and “rehydrates” the components. In heavy JS applications, this process can take several seconds, during which the user sees the page but cannot interact with it.

This directly affects Core Web Vitals, specifically Total Blocking Time (TBT) and Interaction to Next Paint (INP). The business impact is well-documented: the BBC found it lost an additional 10% of users for every extra second of load time. Vodafone reported that a 31% improvement in LCP led to an 8% increase in sales. Rakuten 24, after optimizing Core Web Vitals, achieved a 53.37% increase in revenue per visitor and a 33.13% improvement in conversion rate.


The Hulu Case Study: When Pure JavaScript CSR Destroys Indexation

The documented case of Hulu.com powerfully illustrates what happens when these problems compound. Hulu, the American streaming platform, built its website as a 100% JavaScript Client-Side Rendering application. The SEO result was that searches for content exclusive to Hulu on Google returned virtually no results from hulu.com.

The technical reason was simple but devastating: inspecting the HTML source of any Hulu page revealed only empty containers. <div> tags without content, references to JavaScript files, but no film titles, descriptions, or metadata accessible without executing JS. Googlebot in its first crawl phase saw exactly that — an empty page.

Analysis documented by Onely showed this was not an isolated incident from a company unaware of best practices. It was a systemic consequence of prioritizing web application architecture without considering crawling and indexation requirements. Barry Adams, Technical SEO Consultant at Polemic Digital, captures the structural problem precisely: “JavaScript frameworks are great for building web apps with… However, web apps are not websites.”

The distinction matters. A web application is designed for authenticated users who interact with it repeatedly. A website oriented toward organic traffic capture needs to be crawlable, indexable and visible to search engines from the very first moment a URL is accessed.


Solutions: A Technical Decision Map

Server-Side Rendering (SSR)

SSR is the most robust solution for JavaScript SEO problems. The server executes the JavaScript code and generates complete HTML before sending it to browsers and crawlers. Every URL returns HTML with all content, metadata and structure already rendered.

The main frameworks implementing SSR for each JS ecosystem:

  • React: Next.js (most widely adopted), Remix
  • Vue.js: Nuxt.js
  • Angular: Angular Universal
  • Framework-agnostic: Astro (with SSR output), SvelteKit

SSR eliminates virtually all the problems described in this resource: content is in the initial HTML, metadata is correct from the first crawl, crawl budget is consumed efficiently, and all crawlers — including social media ones — see the complete content.

Static Site Generation (SSG)

SSG, also called pre-rendering, generates the HTML for all pages at build time, before deployment. The result is static HTML files served directly from a CDN, with no per-request server processing.

This is the best possible SEO rendering performance because crawlers receive pure HTML instantly. The limitation is that it is not suitable for frequently changing or user-dependent content. For sites with relatively stable content — blogs, documentation, product pages that do not change constantly — SSG is the optimal choice.

Astro, Gatsby, Next.js with static export, and Eleventy are popular SSG options.

Incremental Static Regeneration (ISR)

ISR, available in Next.js and some other frameworks, combines the advantages of SSG and SSR. Pages are pre-generated as static HTML but can be automatically regenerated on the server when content changes, without requiring a complete site rebuild.

It is particularly useful for sites with large product catalogs or content that updates periodically but not in real time.

Dynamic Rendering as a Transitional Solution

Dynamic rendering serves pre-rendered HTML to crawlers while delivering the full JavaScript version to browsers, using User Agent detection to distinguish between them.

“Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines.” — Google Search Central

Google recognizes dynamic rendering as valid in its official documentation, but also explicitly describes it as a workaround, not a long-term solution. It is useful in gradual migration contexts from a pure CSR architecture when refactoring the entire application to SSR is not immediately feasible.

The most widely used tools for implementing dynamic rendering are Rendertron (open source from Google) and cloud services like Prerender.io.


Rendering Strategy Comparison Table

StrategyIndexabilityPerformanceComplexityBest use case
Pure CSRLow (requires JS rendering)VariableLowApps without SEO requirements
SSRHigh (complete HTML from server)HighMedium-highSites with dynamic content
SSGMaximum (static HTML)MaximumMediumStatic or semi-static content
ISRHighHighMedium-highLarge catalogs with periodic updates
Dynamic renderingMedium (workaround)VariableHighGradual migration from CSR

JavaScript SEO Verification Checklist

Before considering JavaScript SEO problems resolved on a site, systematically verify the following:

  1. Critical content in initial HTML: Is the main text, H1-H3 headings, and metadata present in the server-returned HTML before executing JS?
  2. Clean routing: Do SPA URLs use the History API and not hash routing (#)?
  3. Correct HTTP status codes: Do missing pages return 404, not 200?
  4. Compatible lazy loading: Do images use loading="lazy" or Intersection Observer, not scroll events?
  5. Crawlable pagination: Does paginated content have its own URLs and <a> links in the HTML?
  6. Unblocked JS resources: Does robots.txt not block JS or CSS files required for rendering?
  7. Social crawlers: Are Open Graph tags present in the server HTML?
  8. Core Web Vitals: Are LCP, INP and CLS within Google’s “Good” ranges?

If the answer to any of these questions is no, that item must be included in the technical SEO action plan. For broader indexation issues, our Google indexation problems guide provides a complementary diagnostic framework.


Conclusion

JavaScript SEO problems are not inevitable. They are consequences of architectural decisions that can be corrected. The key insight is that search engines, despite significant improvements in their ability to process JavaScript, still handle static HTML more efficiently, more quickly, and with fewer resource costs.

The goal is not to remove JavaScript from websites, which would be counterproductive for user experience. The goal is to ensure that SEO-critical content is available in the HTML the server returns, regardless of what client-side JavaScript does afterward.

Sites that implement SSR, SSG or, at minimum, critical content in initial HTML not only improve their indexability. They also improve their Core Web Vitals, which has a documented positive effect on conversions, sales and user retention. Addressing JavaScript SEO problems is, in most cases, one of the highest-return technical SEO investments a site can make.

How does JavaScript affect SEO?

JavaScript harms SEO because Googlebot separates crawling from rendering by days or weeks, delaying indexation. Pages that depend on JS for content, metadata or navigation consume more crawl budget, can produce soft 404s, and are completely invisible to social media crawlers that cannot execute JavaScript.

FAQ about JavaScript SEO problems

Can Google index JavaScript-generated content?

Yes, but with important limitations. Google executes JavaScript in a second rendering phase that may occur days or weeks after the initial crawl. During that window, the JS content is not indexed. The process also consumes significantly more crawl budget than static HTML, meaning large sites may have portions of their content left unindexed as a result.

How long does Google take to index JavaScript pages?

According to Google's official documentation, JavaScript rendering happens in a separate queue and can take from a few hours to several days, depending on crawl budget status and the domain's crawl frequency. New pages or domains with low authority may experience even longer delays.

What is dynamic rendering and when should it be used?

Dynamic rendering is a transitional solution that serves pre-rendered HTML to crawlers while delivering the full JavaScript version to browsers. Google recognizes it as valid but explicitly describes it as a workaround, not a long-term solution. It is useful for gradually migrating away from a pure CSR architecture without a full application refactor.

Is SSR necessary for SEO in React or Vue applications?

It is not mandatory, but highly recommended for sites where the main content, metadata or navigation are generated with JavaScript. Without SSR, Googlebot must execute the JS to see that content, introducing indexation delays and consuming crawl budget. For small sites with few pages the consequences are manageable; for enterprise sites, SSR or SSG are practically essential.

How does JavaScript affect crawl budget?

JavaScript increases crawl budget consumption in two ways: first, by requiring Googlebot to execute JS code to render content, a process ~100x more computationally expensive than reading HTML; second, by generating additional JS resources (JS files, fetch/XHR requests) that the crawler must follow and process. This reduces the effective number of pages Google can crawl per session.

How do you do SEO for Single Page Applications?

To optimize SEO for a SPA: use the History API instead of hash-based routing (#), implement SSR or pre-rendering for key pages, ensure each unique URL has its own metadata (title, description, canonical) injected in the initial HTML, configure correct HTTP status codes for errors and missing pages, and verify rendering with Google Search Console's URL Inspection Tool.