Custom Footnotes with MDX in Gatsby
This article was first published in 2019 and this site no longer runs on Gatsby.
MDX offers a pretty straightforward way to handle replacing the default HTML elements via the MDXProvider
component in , but what happens when you need to replace an element that isn’t in the default component list or one that is unique in some way? -js/react
This scenario may come up when using a remark plugin or supported features, such as footnotes[1]. See the final example implementation on codesandbox, or follow along below.
Using the wrapper component
MDXProvider offers a special wrapper key that is primarily used to modify the wrapper around the markdown content. If you dive into the wrapper customization guide, you’ll find that it also provides access to the MDX children components.
We’ll use this functionality to iterate over the children, find the div
with a class of footnotes
(the default from gatsby-mdx), and replace it with a custom component. The component object to be passed to the provider ends up looking like the following:
//
const components = {
wrapper: ({ children, ...props }) => {
// updatedChildren becomes our new list of children, including any modifications
const updatedChildren = children.map((child) => {
if (child.props.className === "footnotes") {
// Since we only have one element that will ever match this
// the key doesn't matter, but react will yell without a key.
return <Footnotes key={1} {...child.props} />
}
return child
})
return <>{updatedChildren}</>
},
}
We can then customize the Footnotes
however we like to style and interact with the footnotes that mdx is bringing in.
Since this is Gatsby we can put the provider into our layout component that handles mdx-specific content, or it can be added to gatsby-ssr
and gatsby-browser
to wrap every page using the wrapRootElement
or wrapPageElement
hooks.
// gatsby-browser.js
export const wrapPageElement = ({ element }) => {
return <MDXProvider components={components}>{element}</MDXProvider>
}
Here’s our final, working example on codesandbox.
Additional Reading
remark wraps footnotes in an outer
div
with a class offootnotes
. ↩︎