Link Checker
Post-build broken link checker that validates internal links in built HTML and MDX source files.
Link Checker
zudo-doc includes a built-in link checker (scripts/) that runs two types of validation after the site is built.
What It Checks
Mode 1: Built HTML scan
Scans all .html files in dist/ for internal <a href="..."> links and verifies each target exists on disk. It handles:
Base path stripping (e.g.,
/→my- docs/ docs/ foo docs/foo)Trailing slash resolution (
docs/foo/→docs/)foo/ index. html Extension resolution (
docs/foo→docs/orfoo/ index. html docs/)foo. html Query string and fragment stripping before resolution
Relative link resolution against the file's directory
Caching resolved paths for performance
Links that are skipped (not checked):
External URLs (
https:,/ / http:)/ / Anchor-only links (
#section)mailto:,javascript:,data:,tel:URIsVersioned docs links (
/) — version content may be incompletev/ */
Mode 2: MDX source scan
Scans all .mdx and .md files in the configured content directories for absolute links that bypass the base path. This catches links like:
<!-- These are flagged — they bypass the base path -->
[guide](/docs/guides/foo)
<a href="/ja/docs/guides/foo">link</a>
<!-- These are fine — they use relative paths -->
[guide](./foo.mdx)
[guide](../other/bar.mdx)When a base path is configured (e.g., /), absolute links starting with / or / will break because they're missing the base path prefix. The MDX source scan catches these before they become broken links in production.
Links inside fenced code blocks are ignored.
Running the Link Checker
Standalone
Build the site first, then run the checker:
pnpm build && pnpm check:linksFailure category flags
By default, the checker exits with code 0 even when issues are found. Select the categories that should fail the command with the explicit --strict-broken, --strict-absolute, and --strict-trailing flags. The b4push and CI workflows fail on broken links and absolute MDX links while leaving trailing-slash findings informational:
pnpm check:links -- --strict-broken --strict-absolute --allowlist=.check-links-allowlistRun pnpm check:links -- --help to see the current CLI options.
Allowlist
--allowlist=PATH excludes exact <file>:<line>:<href> entries from the strict-mode failure counts — for issues that cannot be fixed at the source, such as a JA page that intentionally links to an EN-only sibling, or an absolute href that resolves to a runtime-generated route with no MDX file. The repo ships a real allowlist at .check-links-allowlist: one <file>:<line>:<href> entry per line, with # comments and blank lines ignored. Each entry must match the printed report verbatim — file path relative to the repo root, 1-based line number, and href as it appeared in the source or built HTML. Delete an entry once its underlying issue is fixed, so the strict gate catches future regressions of the same shape.
As part of b4push
The link checker runs as step 20 of 23 in the pre-push validation (pnpm b4push), right after the build step:
19. Build
20. **Link check**
21. HTML validationThe canonical, authoritative b4push step list lives in the header comment of scripts/ — treat that script as the single source of truth for the full 23-step sequence.
In CI
The link checker runs in the build-site job of the PR checks workflow (pr-checks.yml), immediately after pnpm build.
Output
When no issues are found:
Checking links (base: /my-docs/)...
✓ No broken links or absolute path issues foundWhen issues are found:
Checking links (base: /my-docs/)...
=== Broken Links in Built HTML ===
dist/docs/page/index.html:42 /my-docs/docs/missing-page
=== Absolute Links Bypassing Base Path (MDX Source) ===
src/content/docs/guides/test.mdx:15 /docs/guides/foo
✗ Found 1 broken link and 1 absolute path warning Each entry shows the file path, line number, and the problematic href.
Configuration
The link checker reads its configuration from the resolved config (the fields you pass to zudoDoc({...}) in zfb.config.ts):
base— The site's base path, used to strip prefixes when resolving linksdocsDir— Primary content directory for MDX source scanninglocales— Locale configurations withdirfields pointing to additional content directories for MDX source scanning (e.g.,locales:){ ja: { dir: "src/ content/ docs- ja" } }