MDX

Use MDX to create pages.

Description

MDX is a format that combine Markdown and JSX, so you can write regular Markdown content and import JSX components. This plugin adds support for MDX to create pages in Lume, by creating files with the .mdx extension.

Installation

The MDX plugin depends on a JSX plugin to work. Use it together with jsx or jsx_preact plugin depending on whether you want to use React or Preact.

This is an example with Preact:

import lume from "lume/mod.ts";
import jsx from "lume/plugins/jsx_preact.ts";
import mdx from "lume/plugins/mdx.ts";

const site = lume();

site.use(jsx());
site.use(mdx());

export default site;

See all available options in Deno Doc.

Plugins

MDX uses Remark and Rehype under the hood, so you can add additional plugins. By default it uses the GitHub-flavored markdown, but you can use the remarkPlugins and rehypePlugins options to add more:

import lume from "lume/mod.ts";
import mdx from "lume/plugins/mdx.ts";
import jsx from "lume/plugins/jsx.ts";
import a11yEmoji from 'npm:@fec/remark-a11y-emoji';
import rehypeRemoveComments from 'npm:rehype-remove-comments@5';

const site = lume();

site.use(jsx());
site.use(mdx({
  remarkPlugins: [allyEmoji]
  rehypePlugins: [rehypeRemoveComments]
}));

export default site;

Components

In MDX you can use the Lume components from the comp global variable variable or import other components like in JavaScript (with import ... from ...):

---
title: Hello world
description: This is a description
---

import Image from "./_includes/Image.tsx";

<comp.Header title={title} description={description}/>

This is a markdown file with the title **{ title }**.

<Image alt="foo" />

MDX is designed to work with JSX components. If you use a component that returns the HTML code as string (for example a nunjucks component) it will be escaped. To avoid that, you have to use the dangerouslySetInnerHTML attribute.

For example, let's say you have nunjucks component to render a title:

<!-- comp.title -->
<h1>{{ text }}</h1>

A way to use it in a mdx file is:

<div dangerouslySetInnerHTML={
  { __html: comp.title({ text: "Hello world" }) }
} />