Link Checker
Automated tool for checking broken internal and external links in documentation.
Overview
The link checker scans all Markdown and MDX files in the documentation for broken links. It validates internal links (between documentation pages) and optionally checks external links (URLs to other websites).
Features
- ✅ Internal link validation - Checks
/docs/paths, relative paths (./,../), and@site/aliases - 🌐 External link checking - Optional HTTP status code checking for external URLs
- 📊 Detailed reporting - Shows file, line number, link, and error for each broken link
- 🚀 Fast execution - Parallel checking and smart caching
- 🔧 CI/CD integration - Can be added to prebuild scripts or GitHub Actions
Usage
Basic link check (internal links only)
npm run check-links
Check external links (slower, requires network)
npm run check-links:external
# or
node scripts/check-links.cjs --check-external
Additional options
# Verbose output
node scripts/check-links.cjs --verbose
# Fail on warnings (exit code 2 for warnings)
node scripts/check-links.cjs --fail-on-warning
# All options together
node scripts/check-links.cjs --check-external --fail-on-warning --verbose
Example output
🔍 Docusaurus Link Checker
Options:
Check external links: No
Fail on warnings: No
Verbose: No
Found 165 markdown files to check
============================================================
RESULTS
============================================================
Files checked: 165
Links checked: 306
Unique external links: 65
Errors: 3
Warnings: 0
❌ ERRORS (Broken Links)
docs/architecture.md:45
Link: /docs/tools/nonexistent-tool
Error: Internal link target not found: /docs/tools/nonexistent-tool
Type: internal
✅ No broken links found!
Link types detected
Markdown links
[Link text](./relative-path.md)
[Link text](/docs/absolute-path)
[Link text](https://external.com)
Test Links: Links marked with <!-- test-link --> comment are skipped during validation. Use this for example links in documentation that intentionally don't exist:
<!-- test-link -->
[Example link](./relative-path.md)
MDX Link components
<!-- test-link -->
<Link to="/docs/your-page">Link text</Link>
HTML anchor tags
<!-- test-link -->
<a href="/docs/your-page">Link text</a>
Exit codes
0- No broken links found1- Broken links found (errors)2- Warnings found (only if--fail-on-warningis set)
Integration with build process
Add to prebuild
To automatically check links before every build, add to package.json:
{
"scripts": {
"prebuild": "node ./scripts/sync-tools.cjs && node ./scripts/validate-mdx.cjs && node ./scripts/check-links.cjs"
}
}
GitHub Actions
Add to .github/workflows/deploy.yml:
- name: Check links
run: npm run check-links
Pre-commit hook
Add to .husky/pre-commit:
#!/bin/sh
cd docusaurus && npm run check-links
What gets checked
Included
- All
.mdand.mdxfiles indocs/directory - All
.mdfiles intools/source directory - Internal links (
/docs/,./,../,@site/) - External links (if
--check-externalis enabled)
Excluded
node_modules/directorybuild/directory.docusaurus/directory- Anchor-only links (
#section) mailto:,tel:, anddata:URLs- Links inside code blocks - Links within fenced code blocks (```) are automatically skipped (they're just syntax examples)
- Test links - Links marked with
<!-- test-link -->HTML comment (for example links in documentation)
Common issues
False positives for generated files
If you get errors for tool documentation links, make sure you've run the sync script first:
npm run prebuild # Syncs tools and validates MDX
npm run check-links
Links to tools/ directory not being caught
Issue: Links like tools/cloudflare-access.md may pass validation even if the tool file doesn't exist in the synced Docusaurus structure.
Why it happens: The link checker validates tools/ paths against the source tools/ directory. If a file exists there but hasn't been synced to Docusaurus (or was deleted), the link will appear valid but will be broken in the live site.
Solution: The link checker now validates tools/ paths against both:
- Source
tools/directory (for source file validation) - Synced
docusaurus/docs/tools/structure (for Docusaurus site validation)
Best practice: Always run npm run sync-tools before npm run check-links to ensure the synced structure is up to date.
External link timeouts
External links timeout after 5 seconds. If you have slow external links, they may be reported as errors. Consider:
- Checking external links separately (without
--check-externalin CI) - Increasing the timeout in
scripts/check-links.cjs - Using a link checker service for external links
Relative path issues
Relative paths must be correct from the source file location. Common mistakes:
<!-- ❌ Wrong - missing ./ -->
<!-- test-link -->
[Link](guide.md)
<!-- ✅ Correct -->
[Link](./guide.md)
<!-- ❌ Wrong - wrong directory -->
<!-- test-link -->
[Link](../nonexistent-dir/guide.md)
<!-- ✅ Correct - verify the directory exists -->
<!-- test-link -->
[Link](../existing-dir/guide.md)
Best practices
- Run locally before committing - Catch broken links early
- Use absolute paths for internal docs -
/docs/pathis more reliable than../../path - Check external links periodically - Don't run on every build (too slow)
- Fix broken links immediately - Don't let them accumulate
- Use
@site/for non-doc files - e.g.,@site/src/components/Button
Related tools
- Documentation Verification - Tracks documentation freshness
- Repository Structure - Project organization and sync scripts
Troubleshooting
Script won't run
Make sure the script is executable:
chmod +x docusaurus/scripts/check-links.cjs
Permission errors
Run with Node directly:
node docusaurus/scripts/check-links.cjs
Out of memory errors
If you have thousands of files, increase Node memory:
NODE_OPTIONS="--max-old-space-size=4096" npm run check-links
Configuration
To customize the link checker, edit scripts/check-links.cjs:
// Timeout for external links (milliseconds)
const EXTERNAL_LINK_TIMEOUT = 5000;
// Directories to exclude
const EXCLUDED_DIRS = ['node_modules', 'build', '.docusaurus'];
// File extensions to check
const FILE_EXTENSIONS = /\.(md|mdx)$/i;
Test Links and Code Block Links
Automatic Skipping
Links inside code blocks are automatically skipped - Any link within a fenced code block (```) is treated as a syntax example and not validated. This means you don't need to mark example links in code blocks.
Manual Test Link Marking
For links in regular markdown content (not in code blocks) that are intentionally broken examples, mark them with <!-- test-link --> HTML comment:
Syntax:
<!-- test-link -->
[Example link](./non-existent-path.md)
The comment must appear on the line immediately before the link (or on the same line before the link). The link checker will skip validation for these links and not report them as errors.
Use cases:
- Template placeholders - Links in templates that will be replaced
- Intentional broken links - Links used to demonstrate error handling
- Example links outside code blocks - When showing link syntax in regular markdown
Best Practice:
- Links in code blocks (```) are automatically skipped - no marking needed
- Use
<!-- test-link -->only for links in regular markdown content - Use test links sparingly and only for legitimate examples
- Real broken links should always be fixed, not marked as test links
Future improvements
Planned features for the link checker:
- Test link support (via
<!-- test-link -->comment) - Link caching to avoid rechecking unchanged files
- Parallel external link checking for better performance
- JSON output format for CI/CD integration
- Link ignore list (
.linkignorefile) - Automatic link fixing suggestions
- Integration with Docusaurus build process