Render markdown files into HTML with syntax highlighting and frontmatter.
Overview
The markdown plugin uses marked.js, which is automatically loaded from its CDN when an x-markdown directive is encountered in the current view. Parsed markdown content is cached to avoid re-processing if unchanged.
All headings generated from markdown content (<h1> to <h6> elements) will have IDs automatically generated for anchor linking.
Setup
Markdown is included in manifest.js with all core plugins, or can be selectively loaded.
Markdown can be written directly inside elements using the x-markdown directive, with content wrapped in single quotes.
<divx-markdown="'This is **bold** and *italic* text with a [link](/).'"></div>
Dynamic Content
Markdown content can use Alpine expressions for dynamic updates, including template literals with variables. Scope variables and member chains evaluate directly — x-markdown="post.body", or x-markdown="m.body.text" inside an x-for — with no wrapping needed. An undefined step mid-chain (data still loading) renders nothing instead of throwing, and a single bare word evaluates when defined in scope, otherwise rendering as literal text.
<divx-data="{ title: 'Your Bank Account', count: 0 }"><divx-markdown="`# ${title}
Your balance is $**${count}**.`"
></div><button @click="count++">Print Money</button></div>
File Content
Load markdown content from external .md files by providing a file path like x-markdown="/assets/menu.md". A path must be a single whitespace-free token — a .md/.markdown file or a slash path — so dynamic prose containing slashes is never mistaken for a file.
<divx-markdown="'/assets/menu.md'"></div>
### Menù del Giornaliero- Vitello alla Milanese
- Lasagna alla Bolognese Bianca
- Grilled Cheese n' Taters
From Data Source
The markdown file's path can also be populated from a data source.
This girl is the nastiest skank bitch I've ever met.
Do not trust her.
She is a fugly slut!!
This approach is ideal for blogs, articles, or any content managed through data sources that can leverage markdown files rather than large text blocks. It's also possible to make loading contingent on a URL route (e.g. .../blog/burn-book), use the $route() function:
The $route('path') function searches the data source for an item where an arbitrary property like path matches any segment of the current URL. When found, it returns that item, allowing access to its other properties like article. This enables route-specific content loading without manual URL parsing, and is how this very Markdown article is rendered.
Markdown Syntax
See this Markdown Guide for supported syntax in addition to HTML. Manifest also provides additional support for components, callouts, previews, and code blocks.
Components
A component tag placed in a markdown file will render the component in position.
Kaffee: I WANT THE TRUTH!
Col. Jessup: YOU CAN'T HANDLE THE TRUTH!
<x-disclaimer></x-disclaimer>
<figcaption><spanx-icon="lucide:info"></span>
This is not legal advice.
</figcaption>
Callouts
Callouts highlight specific text in a long form article. They require utility styles and a parent element with the prose class applied.
Use ::: markers to open and close the callout within markdown. Text added to the opening marker's line are treated as CSS classes, useful for adding styles like Manifest utility colors. A leading icon can also be added with icon="..." anywhere in the same line.
If the project includes code block support, markdown automatically converts ``` markers to Manifest <pre x-code> elements, with syntax highlighting support.
For a group of code blocks that can be tabbed through, wrap the blocks in <div x-code-group> tags in the markdown file, with blank lines between the tags and each block.
Attributes
Code blocks support useful attributes in the opening marker's line:
Code language - a supported lowercase language name directly after the backticks (e.g. ```css) enables syntax highlighting.
Title - a snippet title can be added in quotes (e.g. "example.json"). This automatically becomes the tab text for snippets in code groups.
Line numbers - add lines for line numbers.
Copy button - add copy for a button that copies the block's contents.
Collapse="#" - add collapse with an integer value representing the number of lines visible by default, with an expand/collapse button below.
Tab indents are typically preserved. If the language is HTML, HTML tags will be preserved as strings and don't require escape characters.