Skip to content

A rehype plugin for MDX to prevent the use of components

License

Notifications You must be signed in to change notification settings

remcohaszing/rehype-mdx-constant-elements

Repository files navigation

rehype-mdx-constant-elements

github actions codecov npm version npm downloads

A rehype plugin for MDX to prevent the use of components.

Table of Contents

Introduction

MDX can be customized using components. These can be passed using the components prop, or a provider. This applies to hast elements. hast elements can come from the following places:

  • Markdown syntax in either markdown or MDX files:
    **This is strong text.**
  • rehype plugins
  • Markdown files processed with rehype-raw

The customization mechanism is a powerful feature, but most people only provide a few custom components. This plugin allows you to opt out of this customization.

This plugin does nothing for:

  • Explicit JSX elements in MDX files. These already can’t be customized. For example:
    <div />
  • Provided custom components JSX. There is no obvious replacement for these. You need to import those instead. For example:
    <YourComponent />
    <your.component />

Should I use this?

This plugin reduces some runtime overhead by moving it to build time. This is typically useful if you build the MDX code on the server or a build tool, but you run it in the client. Since MDX often contains a lot of static content, this allows the React Compiler to optimize the MDX output significantly.

Installation

npm install rehype-mdx-constant-elements

Usage

This plugin

For example, given a file named example.mdx with the following contents:

**Hello world!**

The following script:

import { readFile } from 'node:fs/promises'

import { compile } from '@mdx-js/mdx'
import rehypeMdxConstantElements from 'rehype-mdx-constant-elements'

const { value } = await compile(await readFile('example.mdx'), {
  jsx: true,
  rehypePlugins: [rehypeMdxConstantElements]
})
console.log(value)

Yields:

/*@jsxRuntime automatic*/
/*@jsxImportSource react*/
function _createMdxContent(props) {
  return (
    <p>
      <strong>{'Hello world!'}</strong>
    </p>
  )
}

export default function MDXContent(props = {}) {
  const { wrapper: MDXLayout } = props.components || {}
  return MDXLayout ? (
    <MDXLayout {...props}>
      <_createMdxContent {...props} />
    </MDXLayout>
  ) : (
    _createMdxContent(props)
  )
}

API

The default export is a rehype plugin.

Options

The option is a hast-util-is-element test. For example, the following tests only apply the plugin to <img> elements:

import { compile } from '@mdx-js/mdx'
import rehypeMdxConstantElements from 'rehype-mdx-constant-elements'

compile(content, { rehypePlugins: [[rehypeMdxConstantElements, 'img']] })
compile(content, { rehypePlugins: [[rehypeMdxConstantElements, ['img']]] })
compile(content, {
  rehypePlugins: [[rehypeMdxConstantElements, (element) => element.tagName === 'img']]
})

If no test is provided, the plugin is applied to all hast elements.

Compatibility

This project is compatible with Node.js 18 or greater.

How it works

By default, given the following MDX:

**Hello world!**

Yields something like this:

function _createMdxContent(props) {
  const _components = {
    p: 'p',
    strong: 'strong',
    ...props.components
  }
  return (
    <_components.p>
      <_components.strong>Hello world!</_components.strong>
    </_components.p>
  )
}

With this plugin, it becomes:

function _createMdxContent(props) {
  return (
    <p>
      <strong>Hello world!</strong>
    </p>
  )
}

License

MIT © Remco Haszing

About

A rehype plugin for MDX to prevent the use of components

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project