The mdx-components file
Before we experiment with plugins in one of the next pages, I wanted to first come back to the mdx-components.tsx
file, which we briefly saw when setting up MDX support (at the very beginning of our Next.js 15 setup), as the file is required to make MDX work, but we did not add any components yet
Using this file you can do some of the things a plugin would do, but without having to install an additional package, for example, mdx-components.tsx
is great if we want to quickly and easily replace an HTML Element with a React component
Or we can use it to quickly add a CSS class to HTML elements, for example, add a class to all our <ul>
unordered list elements because the markdown syntax does NOT let us add a class to a markdown element, in a similar way that we add a class to an HTML element, the second difficulty with ul lists, is that the <ul>
element itself is not even part of the markdown syntax:
To solve this, you could add a remark plugin, which would extend the base markdown syntax, but if you want to move your content to another platform someday, then that platform might not understand your custom markdown syntax as the plugin you used to add classes to lists is not installed, which then could create parsing errors on that platform
You could also write a custom react component, but then you would need to manually import and use that react component in every single MDX page. The advantage of using the mdx-components file is that you only need to import a component once. For example, in the next part of this tutorial, we will create a custom link component, which we will only need to import once into the mdx-components file, but it will then transform every link in every page of our project.
In the next chapter we will use the next/mdx mdx-components.tsx
file to add a class to all of our lists without using an extra plugin, without importing a component in every page, and without having to introduce any new markdown syntax
Adding a CSS class to lists using mdx-components
First, open the mdx-components.tsx
(which is in the root of your project) and add an entry for each headline (replace the commented out example), like so:
Line 1: we import the ComponentPropsWithoutRef type from React, this will allow us to add types for the props of each MDX component (which are React components with NO ref)
Line 9: we create a props type for components, we use the ComponentPropsWithoutRef type from react and as it is a generic type that we set to a list ('ul'
) element type
Lines 15 to 19: we create a simple custom component for ul lists and we used the ListPropsType to add type information for the list component props
When you use mdx-components, then the markdown parser will first turn the markdown list into a list (<ul>
) component, we then use the mdx-components file to further transform the list component by adding a custom listContainer
CSS class
CSS class example using a MDX playground page
Next, let's create a new playground to experiment with the mdx-components file
Inside the /app/(tutorial_examples)
folder, create a mdx-components_playground
folder
Then, in the mdx-components_playground
folder, create a page.mdx
file and paste the following content into it:
We wrap our content with the article
HTML element so that the content is not placed directly into the main
HTML element (of our layout), which has a flex-direction set to row, the article
element has a flex-direction of column (we defined all this in our global.css
file which is in the app
folder when we created it)
Now ensure the dev server is running (or launch it using the npm run dev
command), and then in the browser, navigate to http://localhost:3000/mdx-components_playground
, then use your browser developer tools inspect tool and you will see that the <ul>
element now has a class attribute containing the value listContainer
Congratulations 🎉 you just learned how to use the mdx-components file, in other parts of this tutorial, we will edit this file again and add several more features to it
If you liked this post, please consider buying me a coffee ☕ or sponsor ❤️ me on GitHub, as it will help me create more content and keep it free for everyone