menu
up-caret
down-caret

mdx

JSX + Markdown

# General

General Chatter

Trending conversations
Should literal <h1> be contained in a <p>
@sscotth · 5d
Charge - new SSG that accepts mdx
@bz · 3d
How do I install a remark plugin in Parcel
@leifriksheim · 6d
Traversing MDX components
@aroncarroll · 7d
How do I add plugins top gatsby-mdx?
@jesse-graphcms · 14d

@mdx-js/runtime custom components

Jon Sherrard (@jshez) · December 8, 2018 at 1:08am

@mdx-js/runtime custom components

December 8, 2018 at 1:08am

I understand the components object on <MDX components={components}>{mdx}</MDX>; from @mdx-js/runtime is supposed to be for defining custom components for each support MD element. (e.g h1,h2,p,a etc)

However, if we could also pass our own custom components into there, you can create a really interesting runtime, MDX CMS with custom components.

Imagine being able to write this in a browser:

# This is an h1 tag with a custom component
This is a custom paragraph component
<Embed url='https://mobile.twitter.com/wooorm/status/1062403941923803142' />
That was a custom React component that uses an API to get the oEmbed code for any URL.
It was bundled into my application using the mdx-js/runtime and support for defining custom components.

Amazingly this already nearly works, you just have to define your custom components starting with a lowercase letter - which React complains about.

import React from "react";
import MDX from "@mdx-js/runtime";
const Foo = props => <h1>{props.children}</h1>;
const components = {
h1: props => <h1 style={{ color: "tomato" }} {...props} />,
fooBar: props => <Foo {...props} />
};
const mdx = `
# Hello World
## This is a thing
<fooBar>Hello</fooBar>
`;
export default () => <MDX components={components}>{mdx}</MDX>;

A lot of writers I work with are very familiar with HTML, and giving them access to a few pre-bundle React components in their markdown editor could be super powerful.

I can envisage a system with <Embed />, <Footnote />, <Poll />, <PullQuote /> and <Video /> components being really powerful.

Does anyone have any idea, why the components object will freak out when a component is defined in PascalCase ?

Failing case:

import React from "react";
import MDX from "@mdx-js/runtime";
const Foo = props => <h1>{props.children}</h1>;
const components = {
h1: props => <h1 style={{ color: "tomato" }} {...props} />,
FooBar: props => <Foo {...props} />
};
const mdx = `
# Hello World
## This is a thing
<fFoBar>Hello</FooBar>
`;
export default () => <MDX components={components}>{mdx}</MDX>;

December 8, 2018 at 1:12am

December 10, 2018 at 1:44pm

I was going to comment that this is exactly what scope is for, but you already found it!

  • reply
  • like

As for why <foo /> and not <Foo />, I think it's standard for lowercase to be interpreted as HTML tags and uppercase to be interpreted as JSX tags. So the components prop is doing replacements on the HTML tags, and the scope prop is providing a namespace for JSX.

  • reply
  • like

:+1: have added it to the docs as well

  • reply
  • like