Skip to content

"ADR-005: Link Validation Strategy"

ACCEPTED - Implemented in build pipeline

Documentation contains many internal links using relative paths (](./file.md)). These links will break when:

  1. File reorganization - Moving files between directories
  2. Content Collections migration - Moving from docs/ to src/content/
  3. Documentation restructuring - Flattening or reorganizing guide structure

Hard-coded relative links create fragile documentation that breaks silently:

  • Links work in development but 404 in production
  • No build-time validation of internal references
  • Manual link maintenance is error-prone and scales poorly
  • Future Content Collections migration will require link updates
  • Validate all internal links at build time
  • Support both current relative links and future absolute references
  • Fail fast with clear error messages
  • Prepare for Content Collections migration
  • Zero runtime performance impact

Implement build-time link validation using a custom remark plugin.

graph TD
A[Markdown Files] --> B[Remark Plugin]
B --> C{Link Type?}
C -->|Relative ./| D[Resolve from Current Dir]
C -->|Absolute /docs/| E[Resolve from Root]
C -->|External http| F[Skip Validation]
D --> G{File Exists?}
E --> G
G -->|Yes| H[Continue Build]
G -->|No| I[Fail Build with Error]
  1. Remark Plugin (scripts/remark-validate-links.mjs)

    • Processes all .md and .mdx files during build
    • Validates file existence for internal links
    • Supports multiple base paths for future migration
  2. Link Resolution Strategy

    // Priority order:
    1. Absolute paths: /docs/file.md${rootDir}/docs/file.md
    2. Relative paths: ./file.md${currentDir}/file.md
    3. Extension inference: ./file./file.md (with warning)
  3. Error Handling

    • Strict mode: Fail build on broken links
    • Lenient mode: Log warnings but continue
    • Helpful errors: Show file path, line number, target

Rejected - Doesn’t scale, error-prone, reactive not proactive

  • markdown-link-check: External tool, requires separate CI step
  • broken-link-checker: Runtime validation, not build-time
  • remark-validate-links: Existing plugin but limited customization

Rejected - Prefer integrated build-time validation with custom requirements

Rejected - Requires immediate migration, doesn’t solve current link validation

[Link](https://example.com/docs/file)

Rejected - Requires server setup, breaks offline development

  • Build-time validation - Catch broken links before deployment
  • Clear error messages - Know exactly which links are broken and where
  • Future-proof architecture - Ready for Content Collections migration
  • Zero runtime overhead - Validation only during build
  • Gradual migration path - Existing relative links continue working
  • Build time increase - Additional processing during build (minimal impact)
  • New dependency - Requires unist-util-visit package
  • Learning curve - Team needs to understand new link formats
  • Link format flexibility - Support both relative and absolute during transition
  • Configuration required - Need to specify base paths for validation
  • [x] Create remark plugin for link validation
  • [x] Integrate with Astro config (MDX + markdown)
  • [x] Add validation script to package.json
  • [x] Document migration strategy
  • [ ] Test validation with existing documentation
  • [ ] Fix any broken links discovered
  • [ ] Add validation to CI pipeline
  • [ ] Create monitoring for link health
  • [ ] Convert relative links to absolute references
  • [ ] Implement Content Collections schema
  • [ ] Migrate documentation to src/content/
  • [ ] Update link validation config for new structure
astro.config.mjs
[remarkValidateLinks, {
rootDir: process.cwd(),
basePaths: ['/docs', '/src/content'], // Search these directories
strict: true, // Fail build on broken links
validateAnchors: false // TODO: Future enhancement
}]

If validation causes issues:

  1. Disable plugin - Comment out from astro.config.mjs
  2. Lenient mode - Set strict: false to log warnings only
  3. Remove dependency - Uninstall unist-util-visit if needed

All existing relative links continue working without the plugin.

  • Build logs - Show validation results and suggestions
  • CI pipeline - Fail builds on broken links
  • Documentation health - Track link validation over time