All posts

JavaScript URLs: The SEO, A11y & Security Fix Guide

August 26, 2026

What Is a JavaScript URL (the javascript: Pseudo-Protocol)?

A javascript: URL — the javascript pseudo-protocol — is a value placed inside an href attribute that tells the browser to execute a script snippet instead of navigating. The most common form:

Click me

javascript:void(0) runs whatever follows javascript: and discards the result with void(), preventing the browser from replacing page content with the return value. It became popular as an easy way to make an tag "clickable" without a real destination — no reload, no jump to the top of the page like a bare href="#" causes.

The problem: this one line quietly creates three separate failures — a crawlability gap that hides content from Google, an accessibility break for anyone not using a mouse, and a documented cross-site scripting entry point. Each deserves explanation, though the fix is the same for all three.

The SEO Problem: Googlebot Can't Reliably Follow Them

Google's crawling guidance is direct: to be treated as a crawlable link, an tag needs a real URL in its href attribute. When href contains javascript:void(0) instead of an actual path, Googlebot has nothing to extract, so the link is effectively invisible for crawling and indexing — confirmed in Google's link best practices documentation.

So a javascript url behaves like a missing href: no link equity flows through it, the destination gets no internal-linking signal, and if that page has no other discoverable path, it may never be indexed. Google's Martin Splitt has made the same point repeatedly in Search Central discussions: Googlebot doesn't execute onclick handlers to discover navigation, it parses href values. If your primary navigation, pagination, or product links rely on javascript: hrefs, you're asking Google to guess at a site structure it can't see. This is a close cousin of the malformed-URL problem — a link exists in the DOM but resolves to nothing a crawler can follow. See malformed URLs and how to fix them for a related category of broken href.

The Accessibility Problem: Broken Experience for Screen Readers and Keyboard Users

Screen readers and keyboard navigation depend on href carrying real, predictable information. When a link's destination is javascript:void(0), assistive technology has nothing meaningful to announce — the user hears "link" with no indication of where it goes, because there's nowhere to go. That breaks a core expectation in WCAG guidance: links should navigate, and controls that trigger actions should be marked up as controls.

Keyboard users face a related issue: native anchors are focusable and activate with Enter by default, but developers pairing javascript: hrefs with onclick handlers often wire them to fire only on mouse clicks, silently excluding anyone tabbing through the page. Lighthouse and most accessibility auditors flag this pattern because it conflates "link" semantics with "button" behavior — screen reader users can't distinguish a real navigational link from a fake one until they activate it and nothing happens.

The Security Problem: javascript: URLs as an XSS Vector

Beyond SEO and accessibility, the javascript: scheme is a documented XSS injection point. Because the browser executes anything following javascript: in an href or src attribute, that attribute becomes a direct code-execution channel — no

This keeps a crawlable, accessible href in place while giving you full control over client-side behavior — including apps using the History API for pushState routing.

If it doesn't navigate at all — a dropdown toggle, a modal opener, a "load more" trigger — it isn't a link and shouldn't be marked up as one. Use a native

As defense-in-depth against XSS, pair this with a Content Security Policy (CSP) that restricts inline script execution — it won't fix a bad href pattern, but it limits the blast radius if one slips through.

How to Find Every javascript: URL on Your Site

On a small site, view-source or your browser's inspect-element panel plus a quick search for javascript: in the page source will surface obvious offenders. That works for one page, but it doesn't scale — templated navigation, footers, and third-party widgets tend to repeat the same broken pattern across hundreds of pages, and manual page-by-page searching misses most of them.

An automated crawl is faster: it should walk your full site, flag every href starting with javascript:, and cross-reference those against your accessibility and crawlability audit results in one pass, rather than three separate reports.

Get an Automated Audit Instead of a Manual Grep

Hunting through source code for every javascript:void(0) instance across a large site is tedious and easy to get wrong. Optimevra runs that audit automatically, flagging javascript URLs alongside other broken-link and conversion-killing patterns across your entire site in one scan. If you'd rather see it in action first, check the live demo before running your own audit.

Frequently Asked Questions

Is href="#" bad for SEO?

Yes — it's functionally equivalent to a missing href as far as Google is concerned. Googlebot extracts links from real URLs in the href attribute, so javascript:void(0) passes no link equity and signals no site structure, which can leave dependent pages under-crawled or unindexed.

Can Google crawl or follow javascript: links at all?

No, not reliably. Google's crawling documentation states crawlable links need an actual URL in the href attribute; javascript: pseudo-protocol values don't meet that bar, so Googlebot treats those links as non-navigable.

Why do developers still use javascript: URLs if they're risky?

Mostly habit and convenience — it was historically an easy way to make an element clickable without a real destination or a page jump. It predates wider adoption of preventDefault() and native

Originally published on Rankevra.