Check anchors, duplicate headings, empty link text, and image alt text.
5
links
5
anchors
3
issues
3 in-page links resolved against this document, 1 reference definition. External URLs are never requested.
3 link issues found.
Line 7 — Broken anchor
No heading matches #config.
#config
Did you mean#configuration
Line 15 — Image alt text
Image needs descriptive alt text.
./usage.png
Line 19 — Empty link text
Link text is empty.
https://example.com/env
Anchors in this document
Widget SDK
#widget-sdk
Contents
#contents
Installation
#installation
Usage
#usage
Configuration
#configuration
How to Use
Paste a README, docs page, or any Markdown file into the left pane
Read the counts at the top right — total links, generated anchors, and open issues
Work through the issue list; each entry gives the line number and the offending target
Copy the correct slug from the anchor list, or from the suggestion on a broken link
Fix the source in your editor and paste again to confirm the list is empty
What Gets Checked
Broken in-page links are the most common defect in long READMEs, and they are invisible until someone clicks. A table of contents written by hand drifts as soon as a heading is renamed, and nothing in a normal Markdown build fails when it does. This checker rebuilds every heading anchor the way GitHub would and compares your #fragment links against that list. The whole document is read first, so a contents list at the top resolves against the sections below it.
Missing anchors — a [link](#section) with no heading that generates the slug section, with the nearest real anchor offered when there is one
Duplicate anchors — two headings producing the same slug, where GitHub silently appends -1 to the second one
Undefined references — [text][label] with no [label]: url anywhere in the file, which GitHub renders as literal brackets rather than a link
Empty link text — [](https://example.com), which renders as an unclickable gap and tells assistive tech nothing
Weak image alt text — an empty alt, or a placeholder such as image or screenshot, including badges wrapped in a link
How GitHub builds a heading anchor
GitHub lowercases the heading text, drops punctuation, and replaces each space with a hyphen. So ## Getting Started! becomes #getting-started. Two details trip up most checkers: underscores are kept, so ## get_user_name is #get_user_name, and the slug comes from the text GitHub renders, so ## Install `cli` becomes #install-cli and ## [Docs](https://example.com) becomes #docs. Fenced code, inline code, HTML comments, and YAML front matter are skipped. This is a structural audit only — no external URL is ever requested, so nothing leaves your browser.
Frequently Asked Questions
Does it crawl external URLs?
No. This tool checks Markdown structure locally: heading anchors, duplicate headings, undefined link references, link text, and image alt text. It never makes network requests, so it cannot tell you whether a remote page returns 404.
Which anchor style is used?
GitHub-style heading anchors. Headings are lowercased, punctuation is removed, and spaces become hyphens — the same slug GitHub generates for README and documentation links. Underscores survive, so an API reference heading like get_user_name keeps its anchor, and a heading that contains a link or a code span is slugged from the text GitHub renders rather than from its Markdown source.
Does a table of contents at the top of the file confuse it?
No. Every heading, HTML anchor, and link reference definition in the document is collected before a single link is checked, so a table of contents written above the sections it points at resolves normally. Definitions parked at the bottom of the file resolve the same way.
Why is a duplicate heading reported as a problem?
Two headings with the same text produce the same anchor slug, so GitHub suffixes the later ones with -1, -2, and so on. Any link you wrote to the plain slug then lands on the first heading instead of the one you meant. The suffixed anchor is real, so a link to #usage-1 is accepted.
What counts as missing image alt text?
An empty alt, plus placeholder values that carry no information: image, screenshot, photo, alt text, and missing alt. Screen readers announce those verbatim, so they are treated as unwritten. Badges nested inside a link are checked too, since that is where most unlabelled README images live.
Are code blocks checked?
No. Fenced code blocks, inline code spans, HTML comments, and YAML front matter are all skipped, so example Markdown inside backticks is never reported as a real link or heading in your document.
Is my document uploaded?
No. The whole audit runs in your browser and your Markdown is autosaved only to this browser local storage.