Index of every page on this site: llms.txt
All skills
harlan-zw avatar

/nuxt-link-checker

@77b4558
Run it yourself

Find and fix broken or SEO unfriendly links in a Nuxt app with the nuxt-link-checker module, with the build scan scope, verified config, and the traps that make the checker pass silently or flag valid links. Use when a task mentions broken links, 404 links, link checking on build, failOnError, excludeLinks, excludePages, skipInspections, link checker reports, live inspections, the linkChecker config key, or the link-checker/valid-route ESLint rule.

  • 1 file
  • 8.5 KB
  • MIT
  • Updated last month
  • GitHub
Use this Skill: https://skilld.dev/gh/harlan-zw/nuxt-link-checker/nuxt-link-checker

Nothing lands on disk. Nothing to clean up.

Fork this Skill

Edit a local copy. It keeps the author and licence.

SKILL.md

≈118 tokens for metadata: the name and description. ≈2k when used: this file.

Description uses 5.9% of example budget

Before choosing a Skill, your Agent reads its name and description. All available Skills share that space.

  • A shorter description leaves more room for other Skills. This entry exceeds our 1% size suggestion.

In our Claude Code example, all Skill names and descriptions share 8,000 characters. This Skill uses ≈472 characters, or 5.9%.

The 1% threshold is a size suggestion. Longer descriptions can still fit.

Your model, settings, and other Skills decide how much text your Agent can read.

Example settings and source

The example uses a 200k-token context and default Claude Code settings. The count includes the name, description, separators, and when_to_use when present. Codex also counts local file paths.

Skit's source and limits: Codex 0.160.1, Claude Code 2.1.292.

nuxt-link-checker

Written for nuxt-link-checker v6 on Nuxt 4.6 or Nuxt 5. The module inspects every <a href> in rendered HTML with 15 rules, at build time and in dev. It also ships two ESLint rules. Docs: https://nuxtseo.com/docs/link-checker

Setup

Install with npx nuxt module add link-checker. Config key: linkChecker. The module installs nuxt-site-config for you. Included in @nuxtjs/seo v6. If the app uses @nuxtjs/seo, configure the linkChecker key and do not add the module again.

Set site.url to the production origin. The checker resolves internal links against it (see Traps). The trailing-slash rule reads site.trailingSlash, not a linkChecker option.

Automatic behaviour

  • Build scan. After prerendering, the module inspects the links on each prerendered HTML page. It prints a tree per page, then a summary.
  • Only prerendered pages are scanned. A plain nuxt build with no prerendered routes runs no inspections and logs Nuxt Link Checker scanned no pages. Use nuxt generate, or add routes to nitro.prerender.routes.
  • The whole page is scanned, including <Teleport to="body"> links. An <a> without href gets a no-missing-href warning unless it has role="button".
  • Default exclusions. excludeLinks starts with /^\/_/ and /^\/llms(-[\w-]+)?\.txt$/. Your entries are added to these; they do not replace them. With a non root app.baseURL, the base URL is also excluded.
  • External links are not fetched. fetchRemoteUrls is false, so every absolute external link counts as a 200.
  • Links to files in public/ pass without a request.
  • Dev. With Nuxt DevTools on, the module adds a Link Checker DevTools tab and /__link-checker__/* server routes. On page squiggles need showLiveInspections: true.
  • DevTools host. The DevTools tab needs nuxtseo-devtools-host as a dev dependency. Without it, the tab shows an install button.
  • ESLint. With @nuxt/eslint, the module registers link-checker/valid-route (error) and link-checker/valid-sitemap-link (warn) for .vue, .ts, and .md files.

Fail CI on broken links

export default defineNuxtConfig({
  modules: ['nuxt-link-checker'],
  site: { url: 'https://example.com' },
  nitro: { prerender: { routes: ['/'], crawlLinks: true } },
  linkChecker: {
    failOnError: true,
    report: { json: true, markdown: true },
  },
})

Only errors fail the build. Errors come from no-error-response, missing-hash, and no-javascript. Every other rule is a warning. The count is the number of links with an error, not the number of errors.

With crawlLinks: true, Nitro crawls the broken link too and fails the build on its 404 before failOnError matters. To keep the build green and still get the report, set nitro.prerender.failOnError: false.

Reports

report.html, report.markdown, and report.json write link-checker-report.<ext> to .output/. When any report is on, the console shows only the summary. Read the report file for the link list.

  • report.storage: a path relative to the root, or unstorage options.
  • report.publish: true writes to .output/public/__link-checker__/. It adds X-Robots-Tag: noindex and a robots.txt disallow. The report is still public.

The JSON report is an array of { route, reports }. Each report has link, textContent, error[], warning[], and fix. fix is the suggested link, such as /about for a typo /abot.

Exclude links and pages

export default defineNuxtConfig({
  linkChecker: {
    excludeLinks: ['/admin/**', '/api/*', /\.(pdf|zip)$/],
    excludePages: ['/embed/**'],
    skipInspections: ['link-text', 'no-underscores'],
  },
})
  • excludeLinks matches the link. excludePages matches the page that contains the link and skips all its links.
  • String patterns are radix3 routes, not globs. * is one whole segment and ** is any depth. /_nuxt/file_*.pdf never matches. Use a RegExp for part of a segment.
  • skipInspections takes rule ids. The ids are: absolute-site-urls, link-text, missing-hash, no-baseless, no-double-slashes, no-duplicate-query-params, no-error-response, no-javascript, no-missing-href, no-non-ascii-chars, no-underscores, no-uppercase-chars, no-whitespace, redirects, trailing-slash. An unknown id does nothing and gives no warning.

ESLint without @nuxt/eslint

// eslint.config.mjs
import linkCheckerPlugin from 'nuxt-link-checker/eslint'
import vueParser from 'vue-eslint-parser'

export default [
  {
    files: ['**/*.vue', '**/*.ts'],
    languageOptions: { parser: vueParser },
    plugins: { 'link-checker': linkCheckerPlugin },
    rules: {
      'link-checker/valid-route': 'error',
      'link-checker/valid-sitemap-link': 'warn',
    },
  },
  // Markdown: same plugin and rules, plus processor: 'link-checker/markdown'
]

The rules read .nuxt/link-checker/routes.json. Run nuxt prepare or nuxt dev before eslint in CI. valid-sitemap-link checks nothing until nuxt dev merges the @nuxtjs/sitemap URLs into that file. Pass { rootDir } or { routesFile } as the rule option when ESLint runs from another directory. Only literal links that start with / are checked. Skip one link with rel="nofollow" or an eslint-disable-next-line comment.

Traps

  • No routes.json, no ESLint errors. Without nuxt prepare, both ESLint rules pass every link. ESLint prints one [nuxt-link-checker] ... not found warning, and still exits 0.
  • Links to pages that are not prerendered are checked against the live site. The module sends a HEAD request to site.url + path. A new SSR only page that is not deployed yet reports a 404. A page that exists only in production passes. Add such pages to excludeLinks, or prerender them.
  • Read the failure message, not only the rule id. An HTTP error reports the status the server sent. A server that rejects HEAD with 405 or 501 gets a GET retry. A DNS error or a refused connection reports Could not reach the link (ENOTFOUND) with the cause code. A timeout reports 408.
  • Rules chain on the fix. When one rule proposes a fix, later rules test the fixed link. /about/ that 404s reports only the 404, not the trailing slash.
  • Different results per mode. Build scans read prerender status codes. Dev scans fetch the dev server. ESLint reads route patterns only and ignores excludeLinks.

Version limits

v6 breaking changes and their fixes:

  • Nuxt ^4.6.0 || ^5.0.0 and Node ^22.22.3 || ^24.15.0 || >=26.0.0 are required. Upgrade Nuxt and Node first.
  • The content integration needs @nuxt/content 3.6.0 or later. Migrate the app to Content v3 before you upgrade.
  • nuxt-site-config 5 is required. Change a pinned nuxt-site-config to ^5.0.0.
  • The sitemap integration needs @nuxtjs/sitemap 9 or later. Replace nuxt-simple-sitemap with @nuxtjs/sitemap.
  • no-error-response messages show the status the server sent. Unreachable links show status 0. Update report parsers that expect 404 (Not Found).
  • Import app functions from #link-checker/app and server functions from #link-checker/server.

These v1 options are gone. The module logs a warning that names the replacement, then ignores them:

  • exclude: use excludeLinks.
  • failOn404: use failOnError.
  • siteUrl and trailingSlash: set site.url and site.trailingSlash.

The ESLint rules and nuxt-link-checker/eslint exist from v5.0.0.

Config

  • enabled (true), runOnBuild (true), failOnError (false), debug (false).
  • fetchTimeout (10000 ms), fetchRemoteUrls (false). With fetchRemoteUrls: true the module checks that you are online first and turns itself off if not.
  • Full reference: https://nuxtseo.com/docs/link-checker/api/config

Debug

  • /__link-checker__/debug.json in dev shows the resolved config, including the serialized exclude patterns.
  • debug: true writes debug-link-responses.json next to the reports, with the status the module used for each link.

Source: SKILL.md on GitHub

skilld matched fixed text patterns in SKILL.md and file names. Patterns miss obfuscated code.

skilld run checks every file with the same patterns. It asks for approval before it loads a Skill with a behavior marked Needs approval.

No third-party reports yet.

Signed by skilld at 77b4558. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Activeupdated last month
Other metadata
compatibility
Requires Node.js ^22.22.3 || ^24.15.0 || >=26.0.0. Requires Nuxt ^4.6.0 || ^5.0.0.

README badge

README badge for harlan-zw/nuxt-link-checker