A JavaScript SEO audit checks whether search engines, AI crawlers, and users can access the same important SPA content. Start by comparing raw HTML, rendered HTML, metadata, internal links, schema, crawl access, and conversion-critical page elements.
A JavaScript SEO audit is a reality check.
It answers one simple question: can search engines, AI crawlers, and real users all access the same important content on your JavaScript-heavy website?
Your site can look perfect in a browser and still be hard for crawlers to discover, render, understand, or trust. If your key content, internal links, metadata, and schema only appear after client-side JavaScript runs, you may not have a content problem. You may have a delivery problem.
Before you blame rankings, rewrite every headline, or assume the algorithm hates you, check whether crawlers can actually see what you’re trying to rank.
Short Answer: What Are You Auditing?
A proper JavaScript SEO audit compares what a user sees in the browser with what crawlers can access before and after JavaScript rendering.
You’re looking for five types of problems:
- Discovery gaps: crawlers can’t find your important URLs.
- Rendering gaps: raw HTML is empty, thin, or missing key content.
- Metadata issues: titles, canonicals, robots tags, or schema show up too late or get overwritten.
- AI crawlability risks: AI crawlers may not execute your JavaScript before extracting content.
- UX and conversion drag: large bundles, slow rendering, hydration issues, and front-end bugs hurt users too.
The blunt version: if your single page app makes the browser do all the work, prove bots can still understand the page. Don’t assume it.
Who This Is For
This guide is for teams running JavaScript-heavy websites where organic visibility matters.
That includes:
- Developers and engineering leads working with React, Vue, Angular, Next.js, Nuxt, Backbone.js, or custom JavaScript apps.
- Technical founders who shipped a polished product but can’t figure out why organic traffic, demo requests, or signups are flat.
- SEO teams responsible for SPA SEO, technical SEO crawlability, AEO, GEO, and AI visibility.
- Growth and marketing teams who suspect the content isn’t the real issue.
- Agencies and consultants auditing modern websites where “view source” and “inspect element” tell two very different stories.
This is not a meta description tune-up. This is a delivery audit.
What to Check First
Pick one important page from your SPA or JavaScript-heavy site. Not a random page. Choose a page that should bring in qualified traffic, such as a product page, service page, pricing page, comparison page, location page, blog post, or use case page.
Now compare three versions of that page:
- What a normal user sees in Chrome
- What appears in the raw HTML source
- What appears after a rendered crawl or headless browser render
You’re looking for the gap between them.
If Chrome shows a full, useful page but the raw HTML looks like this:
<div id="root"></div>
<script src="/bundle.js"></script>
you may have a crawlability problem.
That does not mean Google can’t render the page. Google can render JavaScript. The issue is that rendering is not the same as clean, fast, reliable discovery. Rendering can be delayed, fail, depend on blocked resources, or be incomplete. Other crawlers may not handle your JavaScript the same way Google does. AI crawlers may be even less patient.
For a serious crawlability audit, gather Google Search Console access, a JavaScript-rendering crawler, server logs if available, XML sitemap access, robots.txt access, framework context, deployment context, and a list of priority URLs by business value.
Don’t audit random URLs first. Audit the pages that make money.
1. Discovery and Internal Linking
Crawlers need paths. SPAs often hide those paths behind client-side behavior, especially when navigation is handled with JavaScript instead of normal links.
Check:
- Important pages have unique, crawlable URLs.
- Internal links use standard anchor tags, like
<a href="/page">. - Navigation does not rely only on
onClick, buttons, spans, or JavaScript-only route changes. - Important pages are not only reachable through filters, tabs, search boxes, or infinite scroll.
- Pagination uses crawlable URLs where needed.
- Faceted pages that should be indexed have distinct URLs.
- URLs do not rely on hash fragments like
#sectionor old#!patterns for primary page discovery. - XML sitemaps include canonical, indexable, 200-status URLs.
- Sitemap URLs do not require JavaScript execution to become meaningful.
- Orphan pages are identified, especially product, service, blog, and comparison pages.
Bad pattern:
<span onclick="navigate('/pricing')">Pricing</span>
Better pattern:
<a href="/pricing">Pricing</a>
This sounds basic, but it breaks all the time. If crawlers can’t find the URL, they can’t rank the URL. If AI systems can’t discover the page, they can’t use it as a source.
2. Raw HTML vs Rendered HTML
This is the heart of JavaScript crawlability. You need to know what exists before JavaScript runs and what only appears after rendering.
Check:
- The raw HTML contains the main topic of the page.
- The primary heading is present in the initial HTML.
- Core body copy is present without waiting for client-side rendering.
- Internal links are visible in raw HTML or reliably available after render.
- Product, service, pricing, author, FAQ, and location content is not hidden behind inaccessible API calls.
- The rendered HTML does not remove important content from the initial HTML.
- The page still makes sense if JavaScript execution is delayed.
- The first meaningful content is not just a blank shell, loading spinner, or placeholder.
Look for missing H1s, intro copy, product descriptions, pricing details, reviews, FAQ content, internal links, breadcrumbs, schema markup, canonicals, and robots directives.
If the rendered page is strong but the raw HTML is empty, you may need server-side rendering, static generation, pre-rendering, or a framework-level fix.
3. Rendering and Hydration Risks
Hydration is where a server-rendered or pre-rendered page becomes interactive. It’s also where SEO signals can quietly break.
Check:
- Server-rendered content matches client-rendered content.
- Hydration does not erase headings, body copy, links, or schema.
- The app does not flash one version of metadata and then replace it with another.
- Client-side state does not rewrite canonical tags incorrectly.
- Lazy-loaded components containing SEO-critical content are rendered early enough to be seen.
- Error states are not served to bots because of blocked APIs or missing headers.
- Important content is not dependent on user interaction.
- Rendering does not require cookies, local storage, or logged-in state for public pages.
- Pages do not produce different SEO-critical output across refreshes.
A common failure mode: the page appears server-rendered, but hydration fails. Users still see something, so nobody panics. But crawlers may see broken, incomplete, or inconsistent markup.
That’s the kind of issue that wastes weeks because everyone says, “It works on my machine.” Maybe it does. Your machine isn’t the crawler.
4. Metadata and Robots Directives
Metadata gets messy in SPAs because the client app often controls the document head. Titles, descriptions, canonicals, robots tags, and social metadata may be injected, changed, or removed after load.
Check:
- Each indexable page has a unique
<title>in the initial HTML. - Each indexable page has a relevant meta description in the initial HTML.
- Canonical tags are present and correct before client-side JavaScript changes the page.
- Robots meta tags are correct in raw HTML.
- There is no accidental
noindexin the initial HTML. - JavaScript does not remove or rewrite robots directives after load.
- Open Graph and social tags are correct where sharing matters.
- Metadata templates are not producing duplicated titles across thousands of URLs.
- Route changes update metadata correctly without polluting indexable URLs.
- Error pages, filtered pages, and parameter URLs have intentional indexation rules.
Be especially careful with noindex. If the raw HTML includes a noindex tag and JavaScript removes it later, you’re playing with fire.
5. Canonicals and Duplicate URL Control
Single page applications can create duplicate or near-duplicate URL patterns without anyone noticing. The app may treat multiple routes as the same page. Search engines may not.
Check:
- Canonicals point to the preferred URL.
- Canonicals are not injected late in a way that creates inconsistent signals.
- Parameter URLs are handled intentionally.
- Trailing slash rules are consistent.
- HTTP and HTTPS versions are consolidated.
- www and non-www versions are consolidated.
- Uppercase and lowercase URL variants do not create duplicates.
- Filtered or sorted versions are indexable only when they should be.
- Client-side routing does not generate multiple paths for the same content.
- Canonical tags match sitemap URLs where appropriate.
In a SPA SEO audit, canonicals are not just another checkbox. They help stop your routing system from creating a duplicate-content mess.
6. Structured Data and Entity Clarity
Structured data helps machines understand what a page is about. That matters for traditional search, rich results, and AI visibility.
Check:
- JSON-LD schema is present in the initial HTML where possible.
- Schema matches visible page content.
- Product, Article, FAQ, Breadcrumb, Organization, LocalBusiness, SoftwareApplication, or Review schema is used only where appropriate.
- JavaScript does not inject schema too late or remove it during hydration.
- Schema is not duplicated across routes.
- Required and recommended fields are not empty.
- Entity names are consistent across page copy, schema, headings, and metadata.
- Breadcrumb schema matches visible breadcrumbs.
- FAQ schema, if used, matches visible FAQ content.
- Structured data is tested on both raw and rendered versions.
Do not use schema as decoration. Use it to clarify what already exists on the page.
7. AI Crawlability, AEO, and GEO
AI search adds another layer to crawlability. Traditional SEO already requires pages to be discoverable, renderable, and trustworthy.
AEO and GEO raise another question: can AI systems extract useful answers, entities, and citations from your site without fighting your front end?
Check:
- Critical content is available in the initial HTML through SSR, SSG, or reliable pre-rendering.
- Pages answer clear questions in plain language.
- Important entities are named consistently.
- Product, service, feature, audience, location, and pricing information is not hidden behind interactions.
- FAQs are visible on-page, not only injected after user action.
- Internal links help crawlers understand topical relationships.
- Schema supports the visible content.
- Pages are not blocked for non-Google crawlers unless intentional.
- robots.txt does not accidentally block resources required to understand the page.
- Key content can be extracted without clicking, scrolling forever, or running complex JavaScript.
Many SPA teams assume “Google can render JavaScript” means everyone can. That is not a safe assumption. For AI visibility, your safest content is content that is easy to fetch, parse, and understand.
8. robots.txt, Status Codes, and Crawl Access
Before blaming rendering, make sure crawlers are allowed to access the site in the first place.
Check:
- robots.txt does not block important pages.
- robots.txt does not block CSS or JavaScript files needed for rendering.
- API endpoints needed to render public content are not blocked if crawlers depend on them.
- Important URLs return 200 status codes.
- Redirect chains are cleaned up.
- Broken routes do not return soft 404s with 200 status codes.
- Real 404 pages return 404 status codes.
- Protected or private app routes are not accidentally indexable.
- Staging or preview environments are not indexed.
- Production pages are not carrying staging
noindexrules.
JavaScript sites often blur the line between “the route exists in the app” and “the server returns a valid page.” Search engines care about both.
9. Core Web Vitals and Performance
Performance is not just a Lighthouse score. It affects crawling, user experience, and conversion.
Check:
- JavaScript bundles are not excessively large.
- Unused JavaScript is reduced where possible.
- Main content is not delayed by heavy client-side rendering.
- Largest Contentful Paint is not slowed by app shell rendering.
- Interaction to Next Paint is not hurt by long JavaScript tasks.
- Third-party scripts are not blocking important rendering.
- Images are optimized and not dependent on late client-side loading.
- Fonts do not cause major layout shifts.
- Lazy loading does not hide important content from crawlers.
- Core Web Vitals are reviewed for priority templates, not just the homepage.
A SPA can feel fast to your team and still be slow for SEO. If your JavaScript takes too long to deliver the message, the page loses twice: once in search and once in conversion.
10. UX and Conversion Risks
A SPA SEO audit should not stop at indexability. If a page gets traffic but fails to convert, the business still loses.
Check:
- The main value proposition is visible without waiting for full app hydration.
- Calls to action appear early and work reliably.
- Forms do not break when JavaScript errors occur.
- Pricing, demo, signup, or checkout paths are crawlable and usable.
- Error states are clear and recoverable.
- Page copy explains what the product or service does without relying on animations.
- Navigation is understandable without app-specific behavior.
- Mobile users can access the same core content.
- Tracking scripts do not slow the page or interfere with rendering.
- Conversion pages are not accidentally noindexed.
The goal is not a green score. The goal is a page that can be found, understood, trusted, and acted on.
11. Framework and Architecture Review
Different JavaScript setups create different SEO risks. React, Vue, Angular, Next.js, Nuxt, Backbone.js, and custom SPAs can all work. But you need to know how each important page is being delivered.
Check:
- The rendering mode is known for each important template.
- Server-side rendering, static generation, client-side rendering, or pre-rendering is documented.
- Developers and SEO teams agree which pages must be indexable.
- Public marketing pages are not treated like logged-in app screens.
- Framework upgrades are tested for rendering changes.
- Route-level metadata is tested after deployments.
- Build changes do not accidentally remove pre-rendered content.
- API failures do not produce thin indexable pages.
- Error boundaries do not hide content from crawlers.
- SEO checks are included before major releases.
The exact fix depends on the stack. The audit pattern stays the same: prove what crawlers get, then fix the gap.
12. Google Search Console Checks
Google Search Console will not tell you everything, but it will show useful symptoms.
Check:
- Important URLs are indexed.
- Important URLs are not stuck in “Discovered, currently not indexed” without explanation.
- Important URLs are not excluded by
noindex. - Google’s selected canonical matches your intended canonical.
- Crawled pages show the expected content.
- Page indexing reports are reviewed by template type.
- Sitemap submissions match your indexable URL strategy.
- Performance data is reviewed for pages that should drive revenue.
- Query data is checked for technical GEO, AEO, and crawlability demand.
- Drops are compared against deployments, migrations, and framework changes.
Treat Search Console as evidence, not a magic oracle. If impressions are weak, pages are excluded, or Google chooses unexpected canonicals, your JavaScript delivery may be part of the problem.
13. Log File and Bot Behavior Review
If you have log access, use it. Logs show what crawlers actually did.
Check:
- Googlebot is crawling important URLs.
- Important sections are not being ignored.
- Crawl frequency changed after a migration or release.
- Bots are hitting redirected or broken routes too often.
- Server responses for crawlers are clean and consistent.
- Static assets needed for rendering are accessible.
- Non-Google crawlers are not accidentally blocked if AI visibility matters.
- Crawl waste is reduced on low-value routes.
- Money pages receive crawl attention.
- Bot behavior aligns with your sitemap and internal linking strategy.
Logs are useful because they show reality: not what the crawler could do, not what the framework should do, but what actually happened.
14. Copy and Content Extraction
JavaScript SEO is not only technical. Once crawlers reach the page, they still need meaningful content.
Check:
- The page clearly states what the company, product, or service does.
- The target audience is obvious.
- The problem, solution, and outcome are explained.
- Important terms are written naturally in visible copy.
- Headings describe the page, not just marketing slogans.
- Feature descriptions are not hidden inside components that require JavaScript to populate.
- FAQs answer real buyer or technical questions.
- Comparison and alternative pages include enough context to be useful.
- Thin pages are improved or removed from indexation.
- AI extraction would produce an accurate summary of the page.
Crawlability gets the page seen. Good copy gets the page understood. Clear conversion paths get the buyer moving. You need all three.
15. CI and Release Monitoring
A one-time audit helps. A repeatable process protects you from regressions.
Check:
- Priority URLs are tested before major releases.
- Raw HTML snapshots are compared over time.
- Rendered HTML snapshots are compared over time.
- Metadata changes are monitored.
- Canonical changes are monitored.
- Robots directives are monitored.
- Schema presence is tested.
- Internal links are crawled after deployments.
- Performance regressions are flagged.
- SEO-critical templates have QA requirements.
JavaScript SEO problems often appear after innocent changes: a route refactor, framework upgrade, hydration fix, analytics script, redesign, CMS change, or deployment config update. None of those sound like SEO projects. They can still break SEO.
How Savage Audit Fits Naturally
Savage Audit is built for exactly this kind of problem.
JavaScript-heavy websites usually sit between three teams:
- Developers care about architecture, deployment, performance, and maintainability.
- SEO teams care about crawlability, indexation, rankings, and structured data.
- Founders and marketers care about pipeline, demos, signups, and revenue.
Everyone can be right and the site can still be broken.
Savage Audit helps identify JavaScript crawlability problems, single page application SEO issues, raw HTML vs rendered HTML gaps, metadata and canonical failures, AI crawlability risks, technical SEO blockers, UX problems, copy gaps, and prioritized fixes your dev team can actually use.
For related technical checks, see the Technical GEO Audit Checklist, the Website Audit Tool for Developers, and the guide to LLMs.txt vs Robots.txt vs Structured Data.
The point is not to shame the stack. React, Vue, Angular, Next.js, Nuxt, Backbone.js, and custom SPAs can all work. The point is to stop pretending the browser experience is the same as crawler access.
Final Takeaway
Your single page application can look beautiful in the browser and still be a search liability.
Do not start with vanity metrics. Do not start by rewriting every headline. Do not assume “Google can render JavaScript” means your crawlability is fine.
Start with proof.
Compare raw HTML against rendered HTML. Check internal links. Verify metadata. Test schema. Review robots directives. Look at crawl access. Then check whether AI crawlers can extract the same core content your users see.
If bots cannot read your app, buyers may never find it. That is the real JavaScript SEO audit.
Common questions
What is a JavaScript SEO audit?
A JavaScript SEO audit checks whether a JavaScript-heavy website can be discovered, rendered, indexed, understood, and ranked by search engines. It compares raw HTML, rendered HTML, metadata, internal links, schema, status codes, performance, and crawl access.
What is an AI crawlability audit checklist?
An AI crawlability audit checklist verifies whether AI crawlers and answer engines can extract useful content from your site. It focuses on raw HTML access, clear copy, structured data, crawl permissions, internal links, and whether important content requires complex JavaScript execution.
How do I check Backbone.js crawlability?
For Backbone.js crawlability, start with routing and raw HTML. Check whether important URLs return meaningful content on direct server requests, whether internal links use crawlable anchors, and whether metadata is available before client-side DOM manipulation.
When should I run a SPA SEO audit?
Run a SPA SEO audit before launches, migrations, redesigns, framework upgrades, and major routing changes. Also run one after unexplained organic traffic drops, indexation problems, canonical issues, or performance regressions.
Why is my SPA indexed but not ranking well?
An SPA can be indexed but still rank poorly if crawlers see thin raw HTML, delayed content, weak internal links, slow rendering, inconsistent metadata, or confusing canonicals. Indexing does not prove search engines fully understood the page.
Keep the diagnosis moving
Run your own public presence audit
See how your website, search footprint, AI visibility, social proof, and conversion trust look from the outside.
