Skip to content

Broken Links

astro-smart-links validates every internal link against the real route table at the end of the build. No routes file and no second build are required.

  1. While Markdown is compiled, the plugin adds classes to external and internal links.
  2. After the build, the integration scans the actual pages in dist to build the complete route table.
  3. Internal links pointing to missing pages are switched to the broken-link class and written to a report.

Link matching ignores query strings and hashes (/about?x=1#team is treated as /about), and handles relative links, the base sub-path and trailingSlash differences.

astro.config.mjs
import { defineConfig } from 'astro/config';
import { smartLinks } from 'astro-smart-links';
export default defineConfig({
integrations: [
smartLinks({
// Write a report next to your project, supports .json and .html
reportFile: '.smart-links-report.json',
// Fail the build when broken links are found, ideal for CI
failOnBroken: true,
}),
],
});

Console output example:

[astro-smart-links] Smart links report (2026-01-01T00:00:00.000Z)
Routes scanned: 42
Links: 180 internal, 12 external, 2 broken
Broken internal links:
/blog/old-post (found in src/content/blog/new-post.md)
/docs/missing (found in src/pages/index.md)

JSON report shape:

{
"generatedAt": "2026-01-01T00:00:00.000Z",
"routes": 42,
"links": { "internal": 180, "external": 12, "broken": 2 },
"broken": [
{
"href": "/blog/old-post",
"pathname": "/blog/old-post",
"sources": ["/path/to/project/src/content/blog/new-post.md"]
}
]
}

For non-Astro projects or already built static sites, use the built-in CLI:

Terminal window
# Check dist and print a console report
npx astro-smart-links check
# Custom directory, report file, exit code 1 on broken links
npx astro-smart-links check --dir dist --output report.json --fail-on-broken
# Print JSON to stdout for CI pipelines
npx astro-smart-links check --json
# Treat PDF, ZIP and other files as valid routes
npx astro-smart-links check --all
npx astro-smart-links check --extensions html pdf zip

CLI options:

Options:
-d, --dir <path> Build directory path (default: "./dist")
-o, --output <path> Write the report to a file
--format <format> Report format: json or html (default: "json")
--json Print the report to stdout as JSON
-a, --all Treat every file type as a valid route
-e, --extensions <ext...> File extensions to include (default: ["html"])
--fail-on-broken Exit with code 1 when broken links are found
-q, --quiet Only print the summary line

Add a shortcut script to package.json:

{
"scripts": {
"check:links": "astro-smart-links check --fail-on-broken"
}
}

Skip drafts and preview links with ignore:

smartLinks({
ignore: ['/draft/', /^\/preview\//],
}),

If broken links are not detected:

  1. Make sure the link is internal (starts with / or is relative), not http(s)://, mailto:, tel: or a # anchor.
  2. Make sure the target page is part of the build output (check the dist directory).
  3. If the site is deployed under a sub-path, make sure the base config matches your links (the plugin handles the prefix automatically).