Markdown
The Markdown flavour Vellum renders and where it departs from GitHub.
Vellum renders CommonMark plus GitHub Flavored Markdown, with a few additions. Anything that works in a GitHub README works here.
What you get
| Feature | Notes |
|---|---|
| Headings | ## to ###### get anchors. See below. |
| Emphasis, lists, blockquotes | Standard CommonMark. |
| Tables | GFM pipe tables. See Tables. |
| Task lists | - [x] done renders a styled checkbox. |
| Strikethrough | ~~gone~~. |
| Autolinks | Bare URLs become links. |
| Footnotes | Text[^1] with [^1]: The note renders a numbered footnote with a back-reference. |
| Code | Fenced blocks are highlighted, and so is inline code tagged with a language. See Code blocks. |
| Images | See Images. |
Vellum also adds ::: directives for callouts, tabs, steps and
cards, <x-…> tags for your own
components, and allowlisted value tags.
Tables
A table is written as a GFM pipe table and needs no options:
- Code in the first column, such as a config key, is never broken across lines.
- The header row of a table that fits the page stays at the top of the window while the reader scrolls through it.
- A table too wide for the page scrolls sideways inside its own frame instead, without a pinned header, and the page keeps its width.
- On a phone each row becomes a block: the first cell in bold, then every other value under its column's heading. Nothing scrolls sideways.
Headings and anchors
Every heading from ## down gets an id and a copy-link button that appears on hover.
The id is generated from the heading text. If two headings on a page produce the same id,
the later ones get a suffix so every link still resolves.
# is reserved for the page title. Set title in frontmatter and the layout renders the
h1 for you. If a page has no frontmatter title and opens with a # Heading, that
heading becomes the title and is removed from the body, so the page does not end up with
two h1s. If the page has both a frontmatter title and a # Heading, the heading stays
and vellum:build warns about it.
The table of contents is built from these headings. A page without any keeps the empty column, so the text width stays the same from page to page.
Give each heading one topic, ideally one thing a reader would ask about. Search returns sections, one heading and the text under it at a time, so a section that covers several unrelated settings is a weak match for each of them. When a section starts collecting leftovers, split it.
Links
Internal links are ordinary Markdown: [Gating](/docs/gating).
A link to a host other than the one in app.url gets target="_blank", rel="noopener"
and a small outward arrow, so readers can tell it leaves the site before they click.
Links with javascript: and other unsafe schemes are stripped.
Raw HTML is removed
Markdown is parsed with html_input: strip, so a <details>, <div> or <img> written
straight into a page is removed without a warning. Inside a paragraph only the tags go and
the text between them stays: Before <details>x</details> after renders as
Before x after. HTML that starts on its own line forms an HTML block, and the whole block
is dropped, text included.
This keeps docs files from injecting arbitrary markup into the layout. When Markdown cannot express what you need, write a Blade component. See Extending.
No Blade
{{ }}, @if and @php are never compiled in a docs file. They render as the literal
characters you typed, in prose, in code and inside component attributes.
To show a real application value, use an allowlisted value tag.
Frontmatter
YAML between --- fences at the very top of the file:
---
title: Billing
description: How invoices are generated.
---
Configuration lists every key. Unknown keys are kept and ignored.
Note: Save the file as UTF-8 without a BOM
A byte order mark sits in front of the opening ---. Vellum strips a leading BOM so the
frontmatter still parses, but other tools that read your Markdown may not.