✨ Publier v1 is live — a polished docs platform built for the open web.
Skip to content

Markdown syntax

Live cheatsheet of every markdown feature Publier ships out of the box — GFM (tables, task lists, strikethrough, autolinks, footnotes), frontmatter, directive callouts, and the raw-HTML escape hatch.

A live reference for everything the MDX pipeline understands without extra setup. Each section shows the source on the left of the code fence and the rendered result below.

Frontmatter

Every page starts with a YAML block. Astro reads it into the page’s content collection schema; Publier’s nav, sidebar, and SEO use these fields automatically.

---
title: Page title
description: 1–2 sentence summary used in search + meta description
---

Defined by remark-frontmatter (auto-wired by Astro’s MDX integration). Add custom fields freely — they survive into the rendered page’s frontmatter export.

GFM — tables

Pipe-delimited markdown tables, alignment via :--- / ---: / :---:.

| Feature | Status | Notes |
| ------------ | :------: | ---------------------- |
| Tables | shipped | this is one |
| Task lists | shipped | see below |
| Strikethrough| shipped | ~~deprecated stuff~~ |
| Footnotes | shipped | [^1] |
FeatureStatusNotes
Tablesshippedthis is one
Task listsshippedsee below
Strikethroughshippeddeprecated stuff
Footnotesshipped1

GFM — task lists

Tick boxes inside list items.

- [x] Build the parser
- [x] Wire up the renderer
- [ ] Document the syntax
- [ ] Ship to production
  • Build the parser
  • Wire up the renderer
  • Document the syntax
  • Ship to production

GFM — strikethrough

~~tilde-wrapped~~ text renders with a line through it.

The old API was ~~mostly fine~~ unmaintainable.

The old API was mostly fine unmaintainable.

Bare URLs and email addresses get linked automatically — no need to wrap them in <...> or [...](...).

Read more at https://publier.net or mail us at [email protected].

Read more at https://publier.net or mail us at [email protected].

Container directives

Triple-colon blocks parsed by remark-directive and rewritten into Publier’s <Aside> callouts. Four variants ship — note, tip, caution, danger. See the full reference at Callouts.

:::tip
Use `bunx publier` to try a one-off command without installing the native CLI.
:::

Inline directives (:foo[label]{attr=val}) and leaf directives (::break{align=center}) are also parsed, but Publier ships handlers only for the four container types listed above. Any unhandled directive passes through as a plain HTML node — fine for inert markup, never for user input (see Raw HTML below).

Math (opt-in)

KaTeX, behind docsShell({ math: true }). Wrap inline in $...$ or block in $$...$$. Full demo at Math equations.

Raw HTML — what we DON’T do, and why

Publier intentionally does not wire rehype-raw into the pipeline. Raw HTML in MDX is a footgun: a <script> or an onclick= attribute in user-authored content turns into an XSS sink the moment your docs accept community contributions or render markdown from a CMS.

If you control every author and want raw HTML anyway, the safe pattern is the rehype-raw + rehype-sanitize pair:

astro.config.ts
import { docsShell } from '@publier/shell/integration';
import rehypeRaw from 'rehype-raw';
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
export default defineConfig({
integrations: [docsShell()],
markdown: {
rehypePlugins: [
rehypeRaw,
// sanitize-after-parse — never trust raw HTML before it's been allow-listed
[rehypeSanitize, {
...defaultSchema,
// allow only the tags + attrs you actually need
tagNames: [...(defaultSchema.tagNames ?? []), 'iframe'],
attributes: {
...defaultSchema.attributes,
iframe: ['src', 'title', 'width', 'height', 'allow'],
},
}],
],
},
});

Order matters — rehype-raw first to lift HTML into the AST, rehype-sanitize after to strip anything outside the allow-list. Never run rehype-raw without a sanitizer if any of your content comes from untrusted authors.

For most docs sites, the right answer is “use a Publier component instead.” If you find yourself reaching for <iframe>, <details>, or a custom card layout, see Components — most of it is already there.

Pretty quotes / em-dashes (opt-in)

remark-smartypants converts "foo"“foo” and --. Not auto-wired (it’s stylistic). Add it via markdown.remarkPlugins — see Plugins.

Code fences

Fenced code goes through astro-expressive-code for syntax highlighting, copy buttons, and titles. Full reference at Code blocks. Quick examples:

```ts title="hello.ts"
const greet = (name: string) => `Hello, ${name}!`;
```
hello.ts
const greet = (name: string) => `Hello, ${name}!`;

What’s auto-wired vs. what isn’t

PluginAuto-wiredWhy
remark-frontmatterRequired for every page
remark-gfmUniversal expectation in docs
remark-directivePowers :::tip callouts
remark-asides (Publier)Renders directive nodes into <Aside>
remark-math + rehype-katexopt-inHeavy peer deps; only enable when needed
astro-mermaidautoDetected when a mermaid fence appears
remark-smartypantsStylistic; opinionated
rehype-rawSecurity risk by default; opt-in only
rehype-sanitizePair with rehype-raw if you opt in
rehype-formatPretty-prints HTML; cosmetic only, no runtime benefit

Anything not listed here is still pluggable — append to markdown.remarkPlugins / markdown.rehypePlugins in astro.config.ts. See Plugins for the integration pattern.

Footnotes

  1. Footnotes work too — remark-gfm lifts them to the bottom of the page.