"ADR-005: Link Validation Strategy"
ADR-005: Link Validation Strategy
Section titled “ADR-005: Link Validation Strategy”Status
Section titled “Status”✅ ACCEPTED - Implemented in build pipeline
Context
Section titled “Context”Documentation contains many internal links using relative paths (](./file.md)). These links will break when:
- File reorganization - Moving files between directories
- Content Collections migration - Moving from
docs/tosrc/content/ - Documentation restructuring - Flattening or reorganizing guide structure
Problem Statement
Section titled “Problem Statement”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
Requirements
Section titled “Requirements”- 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
Decision
Section titled “Decision”Implement build-time link validation using a custom remark plugin.
Architecture
Section titled “Architecture”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]Implementation Details
Section titled “Implementation Details”-
Remark Plugin (
scripts/remark-validate-links.mjs)- Processes all
.mdand.mdxfiles during build - Validates file existence for internal links
- Supports multiple base paths for future migration
- Processes all
-
Link Resolution Strategy
// Priority order:1. Absolute paths: /docs/file.md → ${rootDir}/docs/file.md2. Relative paths: ./file.md → ${currentDir}/file.md3. Extension inference: ./file → ./file.md (with warning) -
Error Handling
- Strict mode: Fail build on broken links
- Lenient mode: Log warnings but continue
- Helpful errors: Show file path, line number, target
Considered Alternatives
Section titled “Considered Alternatives”Option 1: Manual Link Maintenance
Section titled “Option 1: Manual Link Maintenance”Rejected - Doesn’t scale, error-prone, reactive not proactive
Option 2: External Link Checker Tools
Section titled “Option 2: External Link Checker Tools”- 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
Option 3: Astro Content Collections Only
Section titled “Option 3: Astro Content Collections Only”Rejected - Requires immediate migration, doesn’t solve current link validation
Option 4: URL-based References
Section titled “Option 4: URL-based References”[Link](https://example.com/docs/file)Rejected - Requires server setup, breaks offline development
Consequences
Section titled “Consequences”Positive ✅
Section titled “Positive ✅”- 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
Negative ❌
Section titled “Negative ❌”- Build time increase - Additional processing during build (minimal impact)
- New dependency - Requires
unist-util-visitpackage - Learning curve - Team needs to understand new link formats
Neutral 🔄
Section titled “Neutral 🔄”- Link format flexibility - Support both relative and absolute during transition
- Configuration required - Need to specify base paths for validation
Implementation Plan
Section titled “Implementation Plan”Phase 1: Foundation ✅
Section titled “Phase 1: Foundation ✅”- [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
Phase 2: Validation (Next)
Section titled “Phase 2: Validation (Next)”- [ ] Test validation with existing documentation
- [ ] Fix any broken links discovered
- [ ] Add validation to CI pipeline
- [ ] Create monitoring for link health
Phase 3: Future Migration (Optional)
Section titled “Phase 3: Future Migration (Optional)”- [ ] Convert relative links to absolute references
- [ ] Implement Content Collections schema
- [ ] Migrate documentation to
src/content/ - [ ] Update link validation config for new structure
Configuration
Section titled “Configuration”[remarkValidateLinks, { rootDir: process.cwd(), basePaths: ['/docs', '/src/content'], // Search these directories strict: true, // Fail build on broken links validateAnchors: false // TODO: Future enhancement}]Rollback Strategy
Section titled “Rollback Strategy”If validation causes issues:
- Disable plugin - Comment out from astro.config.mjs
- Lenient mode - Set
strict: falseto log warnings only - Remove dependency - Uninstall
unist-util-visitif needed
All existing relative links continue working without the plugin.
Monitoring
Section titled “Monitoring”- Build logs - Show validation results and suggestions
- CI pipeline - Fail builds on broken links
- Documentation health - Track link validation over time
Related Decisions
Section titled “Related Decisions”- ADR-000: Starter Template Architecture - Foundation
- ADR-001: Preact Island Usage Policy - Component architecture
- ADR-002: Performance Budget Strategy - Quality gates