urltoolskit.org
URL utilities, in the browser
Say hi →

HTML link audit

every href and src · anchor text · rel and target · internal vs external · issues flagged

Extracting URLs from HTML with a regex gives you a list. Parsing it gives you the context — which anchor text points where, which links are nofollow, which open in a new tab without rel="noopener", and which anchors have no text at all. Paste a page's source and get the audit, not just the URLs.

Issues

Links

Stats

Ready.

How to use

  1. Paste the HTML — a full page source, an email template, a CMS field, a fragment. It is parsed as an inert document, so nothing in it runs and no requests are made.
  2. Set a Base URL. Without it, relative links stay relative and internal-vs-external cannot be determined; with it, every URL is resolved to absolute form.
  3. Untick element types you do not care about — auditing anchor text is much easier with images and scripts filtered out.
  4. Read Issues first. These are the findings worth acting on, each with the reason it matters.
  5. Copy as TSV pastes into a spreadsheet with the columns split, or download the CSV.

What gets flagged

target="_blank" without rel="noopener". The opened page receives a window.opener reference to yours and can redirect it — the classic reverse-tabnabbing attack. Browsers have implied noopener since 2021, so this is much less dangerous than it was, but in-app webviews and older browsers do not, and it is one attribute.

Empty or generic anchor text. "Click here" and "read more" tell a screen-reader user nothing when the links are read out of context, and they pass no signal about the destination. An anchor wrapping only an image is reported with the image's alt text, since that is what becomes the accessible name — and a missing alt there leaves the link with no name at all.

Same anchor text, two destinations. Two links reading "pricing" pointing at different URLs is confusing for users and ambiguous for search engines. Usually a template bug or a stale hard-coded link.

javascript: hrefs and placeholder #. Neither is a real destination. If it triggers behaviour rather than navigating, it should be a <button> — which is also keyboard-accessible by default.

http:// links from an HTTPS page. For subresources that is mixed content and gets blocked; for anchors it is an avoidable redirect and a downgrade. The mixed-content checker goes deeper on this.

FAQ

Why parse rather than regex?

Because attributes, quoting styles, comments and nesting all defeat regexes eventually — and anchor text simply is not available to one. Using the browser's HTML parser gives the same interpretation a browser would, including how it recovers from broken markup. The URL extractor is the regex-based tool, and the right choice for plain text or logs.

Does it check whether the links work?

No — that needs a request per URL, and a browser tab cannot make cross-origin requests to arbitrary sites. This is a static audit of the markup. Take the URL list to a crawler or a curl loop for status codes.

What does it do with srcset?

Splits it and lists each candidate URL separately, marked (srcset), since a broken candidate in the middle of a srcset is easy to miss otherwise.

Is nofollow still meaningful?

Since 2019 Google treats it as a hint rather than a directive, and added rel="sponsored" and rel="ugc" for paid and user-generated links. Marking paid links is still required by Google's guidelines — the tool reports whatever rel values it finds so you can check the right ones are there.