Writing Pages
Braised Docs uses standard Markdown for all content. There is no custom syntax required for basic pages — just write Markdown.
File location
All content lives in the docs/ directory of your project. Subdirectories are supported at any depth:
docs/
├── index.md
├── getting-started/
│ ├── installation.md
│ └── configuration.md
└── reference/
└── api.md
URLs
File paths map to clean URLs automatically:
| Source file | Output URL |
|---|---|
docs/index.md |
/ |
docs/guide.md |
/guide/ |
docs/getting-started/installation.md |
/getting-started/installation/ |
docs/getting-started/index.md |
/getting-started/ |
Every page is written as index.html inside a directory, which produces clean URLs without file extensions.
Page titles
Braised resolves the page title in this order:
titlein frontmatter- The first
# h1heading in the file - The filename, de-slugged (hyphens and underscores replaced with spaces)
The resolved title appears in the browser tab (<title>), the <h1> at the top of the page, and any breadcrumb trail.
Headings
Use standard Markdown headings. Braised automatically generates anchor IDs for every heading and uses h2 and h3 headings to populate the in-page table of contents in the right sidebar.
## Section title → appears in right-hand TOC
### Subsection title → appears in right-hand TOC
#### Deeper heading → rendered, but not in TOC
Markdown features
Braised uses Goldmark — the same Markdown engine as Hugo — with GitHub-Flavored Markdown extensions enabled:
- Tables
- Strikethrough (
~~text~~) - Task lists (
- [ ] item) - Fenced code blocks with language hints
- Footnotes
- Automatic heading anchor IDs
Code blocks
Fenced code blocks with language identifiers get syntax class hints for styling:
```go
func main() {
fmt.Println("hello")
}
```
Links
Internal links use root-relative URLs:
See the [installation guide](/getting-started/installation/) for details.
Relative links also work and are resolved from the current page's URL.
Content includes
The :::include directive pulls a snippet file into a page before Markdown parsing, so included content is fully first-class: headings appear in the TOC, cross-references resolve globally, and the RAG chunker embeds the content with correct context.
:::include{file="shared/note.md"}
:::
The file path is relative to the project root (where braised.yaml lives). Snippet files should live outside docs/ to avoid being picked up as standalone pages — shared/ is a conventional location:
my-site/
├── braised.yaml
├── shared/
│ └── prereqs.md ← snippet, not a page
└── docs/
├── install.md
└── upgrade.md ← both include shared/prereqs.md
Includes are resolved recursively — a snippet can include other snippets. Cycles are detected and reported as build errors. The same file can be included on multiple pages; it is tracked once per including page for dependency purposes.
When braised serve is running, editing a snippet file triggers a rebuild of every page that includes it.
Custom blocks
Braised supports a Pandoc-style fenced div syntax for structured content components. The block name is the first CSS class:
:::{.callout type="warning" title="Before you begin"}
This step requires admin access.
:::
Structural blocks (those that contain child blocks) use a named close instead of a bare ::::
:::{.tabs}
:::{.tab label="macOS"}
brew install braised
:::{/tab}
:::{.tab label="Linux"}
Download the binary from the releases page.
:::{/tab}
:::{/tabs}
Built-in blocks: callout, details, tabs, code-group, dl, synopsis, pillstrip+when, table, rawhtml. Custom blocks can be added to blocks/ in your site root.
See Custom Blocks for the full reference and live examples. For page-level metadata that controls layout and cross-reference IDs, see Frontmatter.