Direct answer

Important destinations should render as anchor elements with resolvable href values. JavaScript can enhance the interaction, but buttons, spans, click handlers, and framework attributes are not dependable substitutes unless the final output contains a normal crawlable link.

What to remember
  • Judge the final HTML output rather than the name of a framework routing component.
  • Use links for destinations and buttons for actions.
  • Distinct content states need stable resolvable URLs.
  • Test initial HTML, rendered HTML, crawl discovery, destination responses, and server logs.

01

Definition

Flowchart showing a crawlable anchor link surviving HTML extraction, JavaScript enhancement, and destination requests
A dependable internal link exposes a resolvable destination before JavaScript enhancement is required. Credit: Rank Builder SEO Research Desk

A clickable interface element is not automatically a web link.

A human can click a button, a styled div, a router component, a card, or a span with a JavaScript event. A crawler needs a dependable destination it can extract and request.

Google says it can generally crawl links implemented as <a> elements with href attributes that resolve to actual web addresses. It cannot reliably extract destinations from anchors without href, tags pretending to be links, or script-event navigation. SEO link best practices for Google[1]

Use this as the base contract:

<a href="/products/shoes">Shoes</a>

JavaScript may intercept the click for client-side navigation, preload data, animate the transition, update application state, or record an event. The destination must still exist as an ordinary URL.

02

Mechanism

Google can discover links during more than one processing stage.

A simplified path is:

Fetch initial HTML
        ↓
Extract links
        ↓
Render JavaScript when needed
        ↓
Extract links from rendered output
        ↓
Request discovered destinations

A link present in the initial server response can be discovered before rendering. A link added during rendering may also be discovered, but now discovery depends on successful script fetching, execution, rendering, and final markup.

That creates a reliability hierarchy.

Reliable anchor

<a href="/products/shoes">Shoes</a>

The destination is visible in markup and remains usable without JavaScript.

Progressively enhanced anchor

<a href="/products/shoes" onclick="enhanceNavigation(event)">
  Shoes
</a>

The browser can follow the URL normally. JavaScript improves the experience when available.

Framework component with valid output

A component such as:

<Link href="/products/shoes">Shoes</Link>

is acceptable when the actual server or rendered output is:

<a href="/products/shoes">Shoes</a>

Do not approve a component because its name contains Link. Inspect the resulting DOM and server output.

Unreliable navigation imitations

<button onclick="go('/products/shoes')">Shoes</button>
<span onclick="go('/products/shoes')">Shoes</span>
<a onclick="go('/products/shoes')">Shoes</a>
<a href="javascript:go('/products/shoes')">Shoes</a>

These may work for a user in one browser state. They do not create the same dependable URL-bearing link contract.

03

Examples

Links versus buttons

Use a link when activation navigates to another resource.

<a href="/pricing">View pricing</a>

Use a button when activation performs an action in the current interface.

<button type="button" aria-expanded="false">
  Show filters
</button>

A button can open a menu containing links. The destinations inside the menu should still use anchors.

Single-page applications

For distinct content views, use stable paths and the History API.

Google recommends ordinary path URLs rather than fragment-based routes for content that must be discovered. Understand the JavaScript SEO basics[2]

Preferred:

<a href="/products">Products</a>
<a href="/services">Services</a>

Avoid treating fragments as independent pages:

<a href="#/products">Products</a>
<a href="#/services">Services</a>

Client-side code can intercept the first pattern and call history.pushState, but the server must also return a meaningful response when /products is requested directly.

Load more and infinite scroll

A load-more button can improve the interface. It should not be the only route to inventory that needs crawling.

Provide a paginated sequence:

<a href="/articles?page=2">Next page</a>

Then enhance the interaction with JavaScript if desired.

See Infinite Scroll and Pagination SEO for the complete inventory pattern.

Card components

This is dependable:

<article>
  <h2><a href="/articles/example-guide">Example guide</a></h2>
  <p>A concise description of the destination.</p>
</article>

Making the whole card clickable with JavaScript is optional enhancement. Preserve a visible anchor containing meaningful text.

04

Boundaries

Test links at every relevant layer.

View the initial response

Use view source or an HTTP client.

Ask:

  • Is the destination present?
  • Is it inside an anchor?
  • Does the anchor contain href?
  • Is the URL resolvable?

Inspect rendered HTML

Check the final DOM after scripts execute.

Ask:

  • Did hydration remove or replace the anchor?
  • Did the router emit a real link?
  • Does the destination change only after user interaction?
  • Did an error prevent the navigation component from rendering?

Disable JavaScript

A fully interactive application may not function without JavaScript. Important navigation should still expose meaningful URLs where practical.

Crawl the site

Use a crawler that can compare:

  • Initial HTML links
  • Rendered links
  • Status responses
  • Redirect targets
  • Canonicals

Inspect the destination

A perfect anchor to a 404, redirect loop, blocked page, or empty client shell is not a successful link.

Check request logs

Logs can show whether a crawler requested the destination. They cannot prove indexing or ranking.

Common failure cases include:

  • Navigation emitted only after a click
  • Links hidden behind authentication
  • Router components rendering spans
  • href values added after delayed API responses
  • Broken hydration removing server-rendered anchors
  • Blocked JavaScript preventing link generation
  • Fragment routes representing distinct content
  • Link destinations returning the same empty application shell
  • Canonicals rewritten incorrectly after client navigation

Use JavaScript SEO: Crawling, Rendering, and Indexing for the broader lifecycle, Rendered HTML Missing Content for rendering failures, and Orphan Pages SEO when pages appear in a CMS or sitemap but receive no crawlable internal links.

A resilient navigation system begins with the web’s least glamorous and most durable component: an anchor containing a URL.

References

Sources behind this record

  1. Understand the JavaScript SEO basicsGoogle (accessed July 29, 2026)

Corrections

Correction history

No corrections recorded.

To report an error, use the public corrections path.

Claim limit

Search crawlers can sometimes infer or discover URLs through other mechanisms, but script-only navigation is not a dependable internal-link contract.