Links and Cross-References
Braised handles links in Markdown at build time, rewriting them to match the site's clean URL structure and validating that they resolve.
Relative links
Write links to other pages using their source file path, relative to the current file. Braised strips the .md extension and adds a trailing slash at build time.
See the [installation guide](../getting-started/installation.md) before continuing.
Becomes:
<a href="../getting-started/installation/">installation guide</a>
Relative links are resolved by the browser at render time. Because Braised's source directory structure maps directly to output URLs, relative paths in source files produce correct relative paths in the output.
Clean URL caveat: Braised serves each page from a directory URL — docs/content/authoring.md becomes /content/authoring/. Because of this, sibling pages (files in the same source directory) require ../sibling.md, not ./sibling.md. ./ resolves down into the page's own URL directory, not across to the source sibling.
<!-- docs/content/frontmatter.md linking to docs/content/linking.md -->
Correct: [Links](../linking.md)
Incorrect: [Links](./linking.md) ← resolves to /content/frontmatter/linking/
If you find this confusing, prefer braised:ref/ cross-references for links within the same section — they are always correct regardless of URL structure. See Cross-references with braised:ref/ for details.
Absolute links
Paths starting with / are passed through unchanged (.md stripped, trailing slash added):
[Blocks reference](/content/blocks.md)
Becomes /content/blocks/.
External links
Links starting with http://, https://, //, or mailto: are never modified.
Cross-references with braised:ref/
For links that should survive page moves without being updated, use a stable label instead of a file path.
Step 1 — declare an id in frontmatter:
---
title: Installation
id: installation-guide
---
Step 2 — reference it from anywhere in the site:
See the [installation guide](braised:ref/installation-guide) before continuing.
Braised resolves this to the correct URL at build time, regardless of where the source file lives. Moving installation.md to a different directory requires only updating nav.yaml — no link hunt.
With a fragment
To link to a specific heading on the target page, append a fragment:
[Linux install steps](braised:ref/installation-guide#linux)
Braised resolves the page URL and appends the fragment: /getting-started/installation/#linux.
Broken cross-references
An unresolved braised:ref/ link is a build error — the build exits with code 1 and reports the exact file and label. This is intentional: a cross-reference is a stronger contract than a path link, and a missing label always indicates a mistake.
ERROR docs/content/authoring.md unresolved ref: braised:ref/missing-id — no page has id: missing-id
Duplicate labels
If two pages declare the same id, Braised emits a warning and the first definition wins. Rename one of the labels to resolve the conflict.
Link validation
After every build, Braised checks all internal links across all pages against the set of known output URLs. Broken links are reported as warnings — the build still succeeds, but the problems are listed.
WARN docs/content/authoring.md broken link: ./old-page/ (resolves to /content/authoring/old-page/)
This catches broken relative and absolute links that the .md rewriter cannot catch (links to pages that were deleted, renamed, or never existed).
Broken braised:ref/ links are always errors, not warnings. See above.