zfb
GitHub repository

Type to search...

to open search from anywhere

Link validation

Opt-in
Created Jun 24, 2026Takeshi Takatsudo

Validate internal links and anchor fragments at build time to catch broken references before they reach production.

The linkValidation feature walks every <a href> and <img src> in the build and validates that internal links and anchor fragments resolve correctly. Broken links produce build diagnostics — warnings by default, errors when failOnBroken: true is set.

External URLs (http://, https://, mailto:, etc.) are silently skipped by default.

Enable

// zfb.config.ts
export default defineConfig({
  markdown: {
    features: {
      linkValidation: {},   // defaults: warn-only, skip external URLs
    },
  },
});

To make broken links fail the build:

linkValidation: { failOnBroken: true },

What is validated

  • Bare anchor fragments#section-id must match a heading ID in the current file.

  • File links without anchor./other.md must resolve to an existing file under the project root.

  • File links with anchor./other.md#section-id requires both a resolvable file and a matching heading ID in that file.

Heading IDs come from HeadingLinksPlugin, which runs earlier in the same hast phase. The cross-file heading-ID registry is populated during the build so anchor validation works across files. Headings that arrive via transclusion are included in the registry, so ./target.mdx#transcluded-heading validates correctly.

What is skipped

  • External URLs starting with http://, https://, mailto:, or tel:.

  • Links in files rendered without a BuildContext (e.g. simple in-memory pipeline calls without context).

  • Cross-file anchor links whose target file is outside the bundler's walked directories (pages, content collections, components, layouts). These degrade to existence-only validation: the file must exist on disk, but the fragment is not checked. If the target file IS in the build, the fragment is always verified.

Options

  • failOnBroken — when true, broken links emit Error diagnostics (build fails). Default: false (warnings only).

Diagnostic format

Diagnostics follow the shared BrokenLink variant in MarkdownDiagnostic:

  • severityWarning or Error depending on failOnBroken.

  • url — the raw href or src value as written by the author.

  • location.path — absolute path of the source file containing the broken link.

Behavior change in #980

Before #980, cross-file anchor fragments (./other.md#section) were validated only for existence — the fragment itself was not checked against the target file's headings. Starting with #980, the fragment is verified post-compile for every file in the build. Builds that previously passed with a broken cross-file anchor under failOnBroken: true will now fail.

Phase

Runs in two phases:

  1. Per-compile hast phaseLinkValidationPlugin validates same-file anchors (#section-id) immediately and records cross-file fragment candidates for post-compile resolution.

  2. Post-compile bundler pass — after all files have been compiled, the bundler assembles a heading map from every file's recorded headings and verifies each recorded cross-file candidate. Findings are routed through the same severity gate as other markdown diagnostics.

Revision History

Takeshi TakatsudoCreated: 2026-06-25T05:17:25+09:00Updated: 2026-06-25T05:17:25+09:00

AI Assistant

Ask a question about the documentation.