Markdown

Mage Pages uses GitHub Flavored Markdown (GFM) with YAML frontmatter and Shiki-powered syntax highlighting.

Frontmatter

Every markdown page requires YAML frontmatter with at least a title:

---
title: "My Page Title"
description: "Optional meta description"
---

# Content starts here

Required Fields

Field Type Description
title string Page title (required)

Optional Fields

Field Type Description
description string Meta description for SEO

Custom Fields

Add any custom fields you need. Access them via useFrontmatter() in layouts and components:

---
title: "Blog Post"
author: "Jane Doe"
publishedAt: "2024-01-15"
tags:
  - typescript
  - deno
---
import type { LayoutProps } from "@mage/app/pages";
import { useFrontmatter } from "@mage/app/pages/hooks";

export default function BlogLayout(props: LayoutProps) {
  const { author, publishedAt, tags } = useFrontmatter();

  return (
    <article>
      <header>
        <p>By {author} on {publishedAt}</p>
        <div>{tags?.map((tag) => <span key={tag}>{tag}</span>)}</div>
      </header>
      {props.children}
    </article>
  );
}

GitHub Flavored Markdown

All GFM features are supported:

Tables

| Feature | Status |
| ------- | ------ |
| Tables  | Yes    |
| Lists   | Yes    |

Renders as:

Feature Status
Tables Yes
Lists Yes

Task Lists

- [x] Completed task
- [ ] Pending task

URLs and email addresses are automatically linked:

Visit https://example.com or email hello@example.com

Strikethrough

~~deleted text~~

Code Highlighting

Code blocks are highlighted with Shiki. Specify the language identifier after the opening fence (e.g., typescript, python, json):

function greet(name: string): string {
  return `Hello, ${name}!`;
}

Supported Languages

Shiki supports 200+ languages including TypeScript, JavaScript, Python, Rust, Go, and more. Use the language identifier after the opening fence.

Theme Configuration

Configure the theme in your pages options:

const { registerDevServer } = pages({
  markdownOptions: {
    shikiTheme: "github-dark", // Default
  },
});

Available themes include:

  • github-dark (default)
  • github-light
  • one-dark-pro
  • dracula
  • nord

See Shiki themes for the full list.

Wrapper Class

Apply a CSS class to the markdown content wrapper:

const { registerDevServer } = pages({
  markdownOptions: {
    wrapperClassName: "prose dark:prose-invert",
  },
});

This wraps the rendered markdown in:

<div class="prose dark:prose-invert">
  <!-- rendered markdown -->
</div>

Useful with typography utilities like Tailwind's @tailwindcss/typography or UnoCSS's @unocss/preset-typography.

Inline HTML

You can use HTML directly in markdown:

# My Page

<div class="custom-component">
  Custom HTML content
</div>

Back to regular markdown.

Internal links work as expected:

See the [Getting Started](/docs/mage-pages/getting-started) guide.

External links open normally:

Visit [Deno](https://deno.com) for more info.

Images

Reference images from your public directory:

![Alt text](/public/images/screenshot.png)

Or use external URLs:

![Deno logo](https://deno.land/logo.svg)

Markdown in TSX Pages

Need to embed markdown content inside a TSX page? Use the Markdown component:

import { Markdown } from "@mage/app/pages/markdown";

export const frontmatter = { title: "My Page" };

export default function Page() {
  return (
    <div>
      <h1>Documentation</h1>
      <Markdown>
        {`
Here's some **bold** text and a code block:

\`\`\`typescript
const x = 1;
\`\`\`
      `}
      </Markdown>
    </div>
  );
}

See Components for full documentation.

Next Steps

  • Layouts - Wrap content with consistent structure
  • Components - Build interactive TSX pages