---
title: "ESLint Integration"
description: "Validate links in your editor with ESLint rules that check against your app's routes and sitemap."
canonical_url: "https://nuxtseo.com/docs/link-checker/guides/eslint"
last_updated: "2026-05-06T18:46:33.083Z"
---

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

### `link-checker/valid-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`

```vue
<!-- ✅ 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`

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`

```vue
<!-- ✅ 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

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

There are several ways to exclude a link from checking:

### `rel="nofollow"`

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.

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

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

### 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.

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

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

### 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

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

## Manual Setup

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

```js
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

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

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

Both rules accept an options object:

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