Most links appear only after JS: fix crawlability
Links that exist only after JavaScript renders may not be crawled, orphaning pages. Find JS-only link pages and learn how to expose links to crawlers.
What it means
This means your HTML source doesn't contain all the links you expect — they're only visible after JavaScript runs. Googlebot sees the raw HTML first, then processes the JS, so links that appear only after rendering are discovered later or may be missed entirely.
Why it matters
Links in raw HTML are crawled during the initial crawl phase; links only in rendered HTML must wait for the render phase, which adds delay and risk. If JavaScript fails or is blocked, those links disappear from Google's view and your page loses internal link equity. AI crawlers that scrape raw HTML similarly miss content behind interaction.
How to fix it
- Use server-side rendering or static generation so headings, links, and meta exist in the initial HTML response.
- Replace hash-fragment routing (href="#") with real URLs via the History API (window.history.pushState).
- Verify links appear in raw HTML via URL Inspection → Rendered HTML, not just in the browser.
- Ensure noindex is set server-side, not injected by JS, since Google may skip rendering when it sees noindex in raw HTML.
Example
<!-- raw HTML: nav is built by JS, 2 links visible to crawlers -->
<nav id="menu"></nav>
<script>renderMenu()</script><!-- server-rendered nav: real <a href> links in the HTML -->
<nav id="menu">
<a href="/products">Products</a>
<a href="/pricing">Pricing</a>
<a href="/docs">Docs</a>
</nav>Emit real <a href> links in the server HTML. onclick handlers and JS-built menus aren't reliably crawled, so JS-only navigation can orphan the pages it links to.
When it's not a problem
This is fine if your page is intentionally lightweight — few links, no dynamic navigation, and the main content is already in the raw HTML. It's also acceptable for pages that rely on client-side analytics, since Googlebot should use Crawl Stats and URL Inspection instead of JS-driven analytics.
How Crawlinx detects it
We compare internal-link counts in the raw HTTP HTML versus the JS-rendered DOM. When rendered links are more than double the raw count and the gap exceeds 10, most links are JS-only and crawlers may never discover them.
How common is it?
Not yet observed in our audit sample. We publish this explainer because the check runs on every crawl; once an audited site trips it, this page will break the issue down by platform, gatekeeper, vertical and country.
FAQ
- Why do JS-only links hurt crawling?
- Crawlers discover pages by following <a href> in the HTML. If your links are injected by JavaScript, the first-wave crawl sees fewer of them, so linked pages can be found slowly or orphaned entirely.
- Do buttons with onclick count as links?
- No. Google needs a crawlable <a href="/real-url">. A <button> or <div> with a JS click handler that navigates via history.pushState isn't a discoverable link.
- How do I expose links to crawlers?
- Server-render your navigation and in-content links as plain <a href> elements. Keep the JS enhancement, but make sure the anchors exist in the initial HTML response.
Related guides
Audit your own site — free
157 checks, internal PageRank, render-diff. No signup, results in ~30s.