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.
How it works
Section titled “How it works”- While Markdown is compiled, the plugin adds classes to external and internal links.
- After the build, the integration scans the actual pages in
distto build the complete route table. - Internal links pointing to missing pages are switched to the
broken-linkclass 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.
Report output
Section titled “Report output”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: 42Links: 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"] } ]}Checking any build directory with the CLI
Section titled “Checking any build directory with the CLI”For non-Astro projects or already built static sites, use the built-in CLI:
# Check dist and print a console reportnpx astro-smart-links check
# Custom directory, report file, exit code 1 on broken linksnpx astro-smart-links check --dir dist --output report.json --fail-on-broken
# Print JSON to stdout for CI pipelinesnpx astro-smart-links check --json
# Treat PDF, ZIP and other files as valid routesnpx astro-smart-links check --allnpx astro-smart-links check --extensions html pdf zipCLI 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 lineAdd a shortcut script to package.json:
{ "scripts": { "check:links": "astro-smart-links check --fail-on-broken" }}Ignoring specific links
Section titled “Ignoring specific links”Skip drafts and preview links with ignore:
smartLinks({ ignore: ['/draft/', /^\/preview\//],}),Troubleshooting
Section titled “Troubleshooting”If broken links are not detected:
- Make sure the link is internal (starts with
/or is relative), nothttp(s)://,mailto:,tel:or a#anchor. - Make sure the target page is part of the build output (check the
distdirectory). - If the site is deployed under a sub-path, make sure the
baseconfig matches your links (the plugin handles the prefix automatically).