# markdown/no-missing-link-fragments

> Disallow link fragments that do not reference valid headings

`[usage](#usage)` jumps to the "Usage" heading in the same document. When the heading is renamed, the link stays and silently stops working.

A heading's anchor is computed the way GitHub does it: lowercased, punctuation removed, spaces turned into `-`, and `-1`, `-2` added to repeats. An `id` or `name` attribute in HTML, a heading written in HTML and `{#custom-id}` at the end of a heading count too. `#top` and line references like `#L10-L20` are always allowed.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. It needs an ESLint config that says which files are in the language:

{/* skip */}

```js eslint.config.js
import markdown from "@eslint/markdown";

export default [
  {
    files: ["**/*.md"],
    plugins: { markdown },
    language: "markdown/commonmark",
    rules: { "markdown/no-missing-link-fragments": "error" },
  },
];
```

It also works with `markdown/gfm`.

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}

```md
# Getting started

See [usage](#usage).
```

Not reported:

{/* good */}

```md
# Getting started

See [the start](#getting-started), [the API](#api), [the FAQ](#questions) or [the top](#top).

## Reference {#api}

<a id="questions"></a>
```

## Options

| Option         | Default | What it does                                                             |
| -------------- | ------- | ------------------------------------------------------------------------ |
| `ignoreCase`   | `true`  | Ignore case, so `#Usage` matches the anchor `usage`.                     |
| `allowPattern` | `""`    | A regular expression. Fragments that match it are not reported.          |

{/* bad {"options": [{ "ignoreCase": false }]} */}

```md
# Usage

See [usage](#Usage).
```

{/* good {"options": [{ "allowPattern": "^tab-" }]} */}

```md
See [the second tab](#tab-2).
```
