ESLint Integration · Nuxt Link Checker · Nuxt SEO

-
-
-
-

[1.4K](https://github.com/harlan-zw/nuxt-seo)

[Nuxt SEO on GitHub](https://github.com/harlan-zw/nuxt-seo)

Link Checker

-
-
-
-
-
-
-
-
-
-

Search…```k`` /`

v5.0.9

- Playgrounds
- [Discord Support](https://discord.com/invite/275MBUBvgP)

### Getting Started

-
-
-

### Core Concepts

-
-
-
-
-
-
-

Core Concepts

# ESLint Integration

[Copy for LLMs](https://nuxtseo.com/docs/link-checker/guides/eslint.md)

Get instant feedback on broken links directly in your editor. The [ESLint](https://eslint.org) integration provides two rules that validate relative URLs against your app's known routes and sitemap data.

## [Rules](#rules)

### [`link-checker/valid-route`](#link-checkervalid-route)

Checks that relative URLs match a known vue-router route pattern. This catches links to pages that don't exist at all.

**Severity:** `error`

```
<!-- ✅ Valid: /about exists as a page -->
<NuxtLink to="/about" />

<!-- ✅ Valid: matches /blog/:slug dynamic route -->
<NuxtLink to="/blog/my-post" />

<!-- ❌ Error: no route matches /abot -->
<NuxtLink to="/abot" />
```

### [`link-checker/valid-sitemap-link`](#link-checkervalid-sitemap-link)

Checks that relative URLs exist in the sitemap. For dynamic routes, it warns when sibling URLs exist in the sitemap but the linked URL does not.

**Severity:** `warn`

```
<!-- ✅ Valid: /blog/hello-world is in the sitemap -->
<NuxtLink to="/blog/hello-world" />

<!-- ⚠️ Warning: /blog/typo matches /blog/:slug but isn't in sitemap -->
<!-- (while other /blog/* URLs are) -->
<NuxtLink to="/blog/typo" />
```

## [What Gets Checked](#what-gets-checked)

Both rules scan for relative URLs in:

- **Vue templates:** `<NuxtLink to="...">`, `<RouterLink to="...">`, `<a href="...">`
- **TypeScript/JavaScript:** `navigateTo('...')`, `router.push('...')`, `router.replace('...')`
- **Markdown:** `[text](/url)` link syntax (via processor)

External URLs, anchors, mailto/tel links, and dynamic bindings are automatically skipped.

## [Skipping Links](#skipping-links)

There are several ways to exclude a link from checking:

### [`rel="nofollow"`](#relnofollow)

Add `rel="nofollow"` to any link element to skip both rules. This is semantic HTML that signals the link shouldn't be followed by crawlers.

```
<a href="/external-redirect" rel="nofollow">
Skip this
</a>

<NuxtLink to="/unindexed-page" rel="nofollow">
Also skipped
</NuxtLink>
```

### [Static file links](#static-file-links)

Links to static files (served from `public/`) are automatically skipped. This includes `.pdf`, `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.avif`, `.svg`, `.ico`, `.xml`, `.txt`, `.json`, `.js`, `.css`, `.woff`, `.woff2`, and other common asset file extensions.

```
<!-- All skipped automatically -->
<a href="/document.pdf">
Download
</a>

<a href="/favicon.ico">
Icon
</a>
```

### [ESLint inline disable](#eslint-inline-disable)

Use standard ESLint disable comments (`eslint-disable-next-line`) to skip individual lines in Vue templates or scripts.

## [Setup with @nuxt/eslint](#setup-with-nuxteslint)

If you're using `@nuxt/eslint`, both rules are automatically registered. Zero-config.

## [Manual Setup](#manual-setup)

For projects not using `@nuxt/eslint`, import the plugin in your ESLint flat config:

```
import linkCheckerPlugin from 'nuxt-link-checker/eslint'

export default [
  {
    files: ['**/*.vue', '**/*.ts'],
    plugins: {
      'link-checker': linkCheckerPlugin,
    },
    rules: {
      'link-checker/valid-route': 'error',
      'link-checker/valid-sitemap-link': 'warn',
    },
  },
  // For markdown files
  {
    files: ['**/*.md'],
    plugins: {
      'link-checker': linkCheckerPlugin,
    },
    processor: 'link-checker/markdown',
    rules: {
      'link-checker/valid-route': 'error',
      'link-checker/valid-sitemap-link': 'warn',
    },
  },
]
```

## [Prerequisites](#prerequisites)

The rules read route data from `.nuxt/link-checker/routes.json`, which is generated when you run `nuxt dev` or `nuxt prepare`. Make sure to run one of these before linting.

## [How Route Data is Generated](#how-route-data-is-generated)

Route data is collected in two phases:

1. **On `pages:resolved`:** Static page routes and dynamic route patterns (e.g., `/blog/:slug`) are written immediately.
2. **After dev server starts:** If `@nuxtjs/sitemap` is installed, resolved sitemap URLs are merged in, capturing dynamic content from `@nuxt/content`, i18n, and custom sources.

The route file is automatically refreshed when files change during development.

## [Configuration](#configuration)

Both rules accept an options object:

```
{
  "link-checker/valid-route": ["error", {
    "routesFile": "/path/to/routes.json",
    "rootDir": "/path/to/project"
  }]
}
```

[Edit this page](https://github.com/harlan-zw/nuxt-link-checker/edit/main/docs/content/2.guides/5.eslint.md)

[Markdown For LLMs](https://nuxtseo.com/docs/link-checker/guides/eslint.md)

Did this page help you?

On this page

- [Rules](#rules)
- [What Gets Checked](#what-gets-checked)
- [Skipping Links](#skipping-links)
- [Setup with @nuxt/eslint](#setup-with-nuxteslint)
- [Manual Setup](#manual-setup)
- [Prerequisites](#prerequisites)
- [How Route Data is Generated](#how-route-data-is-generated)
- [Configuration](#configuration)

[GitHub](https://github.com/harlan-zw/nuxt-seo) [ Discord](https://discord.com/invite/275MBUBvgP)

###

-
-

Modules

-
-
-
-
-
-
-
-
-

###

-
-
-

###

Nuxt

-
-
-
-
-

Vue

-
-
-
-
-
-
-
-

###

-
-
-
-
-
-
-
-
-
-

Copyright © 2023-2026 Harlan Wilton - [MIT License](https://github.com/harlan-zw/nuxt-seo/blob/main/license) · [mdream](https://mdream.dev)