AvalonAvalon
GitHub

MDX & Markdown

Using MDX files as pages in Avalon with frontmatter, syntax highlighting, and interactive islands.

Avalon has built-in MDX support. Any .mdx file in your pages directory becomes a route, just like .tsx files. You get the full power of Markdown with JSX components, frontmatter, and syntax highlighting out of the box.

Built-in Plugins

Avalon uses @mdx-js/rollup with these plugins pre-configured:

PluginPurpose
remark-frontmatterParses YAML frontmatter blocks
remark-mdx-frontmatterExports frontmatter as named exports
remark-gfmGitHub Flavored Markdown (tables, strikethrough, autolinks)
rehype-highlightSyntax highlighting for code blocks

Basic MDX Page

Create a .mdx file in your pages directory:

---
title: My Page
description: A page written in MDX.
---

# Hello World

This is a paragraph with **bold** and *italic* text.

This becomes a route based on the file path, just like any other page.

Frontmatter

Use YAML frontmatter at the top of your MDX file to define metadata:

---
title: Getting Started
description: Learn how to set up Avalon.
---

# Getting Started

Content goes here...

Frontmatter fields are exported as a frontmatter object and automatically passed to your layout. This integrates with Avalon's metadata system for SEO.

Using Components in MDX

Import and use any component directly in your MDX:

---
title: Interactive Demo
---

import '../components/Counter.tsx'; // [mdx-island-transform] kept for CSS: Counter;

# Interactive Demo

Here's a counter component inline:

<Counter island={{ condition: 'on:visible' }} />

Components used with the island prop are automatically wrapped as islands, just like in .tsx pages.

Syntax Highlighting

Code blocks get syntax highlighting automatically via rehype-highlight. Use fenced code blocks with a language identifier:

```tsx
function Hello() {
  return <h1>Hello World</h1>;
}
```

Avalon includes a syntax-highlighting.css stylesheet. Make sure it's linked in your root layout or HTML template.

Supported Languages

All languages supported by highlight.js work out of the box, including TypeScript, JavaScript, JSX, CSS, HTML, JSON, Bash, and many more.

GitHub Flavored Markdown

GFM features are enabled by default via remark-gfm.

Tables

Task Lists

Strikethrough

Configuration

Customize MDX processing in your Vite config:

// vite.config.ts
export default defineConfig({
  plugins: [
    avalon({
      mdx: {
        // JSX runtime for MDX files (default: 'preact')
        jsxImportSource: 'preact',

        // Enable syntax highlighting (default: true)
        syntaxHighlighting: true,

        // Add custom remark plugins
        remarkPlugins: [],

        // Add custom rehype plugins
        rehypePlugins: [],
      },
    }),
  ],
});

JSX Import Source

By default, MDX files use Preact's JSX runtime. If you want MDX content to use React instead:

mdx: {
  jsxImportSource: 'react',
}

Custom Plugins

Add your own remark or rehype plugins:

import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';

avalon({
  mdx: {
    remarkPlugins: [remarkMath],
    rehypePlugins: [rehypeKatex],
  },
})

MDX vs TSX Pages

Both .mdx and .tsx files work as pages. Use whichever fits:

MDXTSX
Best forContent-heavy pages, docs, blog postsDynamic pages, complex layouts
FrontmatterYAML --- blockexport const metadata object
ComponentsImport and use inlineStandard JSX
Islandsisland prop works the sameisland prop works the same
MarkdownNativeNot available
Data fetchingNot supportedasync page functions

File Conventions

MDX files follow the same routing conventions as TSX:

app/modules/docs/pages/
├── index.mdx          → /docs
├── introduction.mdx   → /docs/introduction
├── guides/
│   ├── deployment.mdx → /docs/guides/deployment
│   └── performance.mdx→ /docs/guides/performance