This repo can automatically discover all existing https://docs.availproject.org URLs and map them to the new Fumadocs URLs. Redirects are enforced at the Next.js middleware layer and validated by tests.
-
Old docs URLs (current production site)
- Generated from the public sitemap:
data/old-docs-urls.json
- Script:
scripts/crawl-old-docs.mjs
- Generated from the public sitemap:
-
New docs URLs (this repo)
- Generated from the MDX filesystem:
data/new-docs-urls.json
- Script:
scripts/list-new-docs.mjs
- Generated from the MDX filesystem:
-
Redirect rules (this repo)
- Manual overrides (hand‑curated):
data/redirects.override.json
- Generated mappings (with confidence + reason, for review):
data/redirects.generated.json
- Runtime rules used by middleware + tests (flat
{ source, destination }[]):data/redirects.runtime.json
- Manual overrides (hand‑curated):
- File:
src/middleware.ts - Behavior:
- Step 1 – Markdown negotiation
- If the request targets
/docs/**andAccept: text/markdown, rewrite to/api/markdown/**(existing behavior preserved).
- If the request targets
- Step 2 – Redirects
- For all other requests (excluding assets and
/api/markdown/**), apply redirect rules:- Normalizes paths (trailing slashes removed).
- Checks 4 variants per request:
pathname/docs${pathname}- normalized versions of both
- Longest‑prefix wins: the rule whose
sourceis the longest prefix of the path is used. - Preserves suffix:
destination + (path.slice(source.length)). - Uses rules from:
data/redirects.override.json(highest precedence)src/lib/redirects/generated.ts(generated mappings)src/lib/redirects/static-rules.ts(coarse prefix rules, e.g./da → /docs/da)
- For all other requests (excluding assets and
- Step 1 – Markdown negotiation
From the monorepo root:
- 1. Crawl the current production docs sitemap (old URLs)
pnpm -C anish-latest/docs-fumadocs redirects:crawl-oldOutputs: anish-latest/docs-fumadocs/data/old-docs-urls.json
- 2. Inventory all new docs routes from MDX (new URLs)
pnpm -C anish-latest/docs-fumadocs redirects:list-newOutputs: anish-latest/docs-fumadocs/data/new-docs-urls.json
- 3. Generate mapping + runtime rules
pnpm -C anish-latest/docs-fumadocs redirects:generateOutputs:
data/redirects.generated.json– explicit mappings with{ source, destination, confidence, reason }src/lib/redirects/generated.ts– TypeScript export used at runtimedata/redirects.runtime.json– flattened{ source, destination }[]for tests and tooling
You can edit data/redirects.override.json at any time and re‑run redirects:generate to apply overrides.
We use Jest (in addition to Vitest) for a Node‑only coverage test that simulates the middleware resolution logic.
- Config:
jest.config.cjs - Test:
__tests__/redirects-coverage.test.js
Run:
pnpm -C anish-latest/docs-fumadocs test -- --runTestsByPath __tests__/redirects-coverage.test.jsWhat it checks:
- Every entry in
data/old-docs-urls.jsonresolves to some redirect rule indata/redirects.runtime.json. - The final destination path is present in
data/new-docs-urls.json(i.e. is a valid new route). - Resolution logic exactly mirrors
src/middleware.ts:- same normalization
- same four
pathsToCheckvariants - same longest‑prefix matching and suffix preservation.
The link validator ensures that internal links inside MDX either:
-
point directly to valid new routes, or
-
are at least covered by a redirect rule.
-
Script:
scripts/validate-internal-links.mjs
Check only (no writes):
pnpm -C anish-latest/docs-fumadocs links:validateAuto‑fix where safe (best‑effort string replacement):
pnpm -C anish-latest/docs-fumadocs links:fixBehavior:
- Scans
content/docs/**/*.mdxfor:- markdown links:
[text](/path) - JSX/HTML
href="/path"/href={'/path'}/href={"/path"}
- markdown links:
- Ignores:
- anchors (
#...) mailto:,tel:- static assets (e.g.
/img/...,/static/...)
- anchors (
- For each internal link:
- If
pathis indata/new-docs-urls.json→ OK. - Else, tries to resolve via
data/redirects.runtime.json.- If that destination is in
new-docs-urls.json, it is suggested/used as a fix. - Otherwise it is reported as broken.
- If that destination is in
- If
Use the report script to inspect and hand‑review the generated mappings, sorted by lowest confidence first:
pnpm -C anish-latest/docs-fumadocs redirects:reportOutput:
reports/redirects-review.md
Sections:
- Grouped by top‑level segment (
da,nexus,user-guides, etc.) - Columns:
old,new,confidence,reason - Intended workflow:
- Review low‑confidence mappings.
- For any that look wrong, add an explicit entry to
data/redirects.override.json. - Re‑run
pnpm redirects:generateand, optionally,redirects:report+ tests.