TLDR; You can use ReactMarkdown custom component 🎉. But how? Read on!
Any front-end developer will eventually find themselves working with the popular React Markdown library at some point.
This holds true for Next.js developers as well. Since Next.js is based on React, using React Markdown seamlessly integrates, requiring just a few steps to get it up and running.
Or does it?
While React Markdown may seem easy to integrate, the reality is that there are certain problems that often arise when combining it with another heavyweight in the world of front-end development today: the widely used Tailwind CSS.
This makes the React Markdown renderer not work properly. So you need to work it out to fix the conflict between React Markdown and Tailwind CSS.
From my own experiences, I've encountered confusing issues that took days to resolve.
Now, I'm excited to share with you how to overcome these challenges, so you won't have to waste valuable hours of productivity.
Be productive. No more guessing why ReactMarkdown doesn’t work in your project 🙌
Prerequisite
As you are looking for solution, it means you already have a working Next.js project, so to fix react-markdown not working in your project, you can jump to the Resolving React Markdown and Tailwind CSS Not Working section.
A Next.js Project
To follow this article, you will need a working Next.js application.
This command below will automate the project using latest template.
All you need to do is just following the step-by-step configuration.
npx create-next-app@latest markdownapp
Creating a Next.js project can sometimes lead to errors.
To avoid that, you can stick to the official source or blog articles that have already been well researched to make this step seamless.
TailwindCSS Integration
Using the above Next.js project, if you select Tailwind CSS, it will be available to be used throughout your project.
However, you may not have selected Tailwind CSS before.
You can integrate the framework into an existing project using the below article.
To ensure you load Tailwind CSS, you must ensure the
global.css
file contains this file@tailwind base; @tailwind components; @tailwind utilities;
React Markdown Integration
Now let's focus on integrating Markdown. You need to import the
ReactMarkdown
component from the react-markdown
library.Integrating React Markdown involves a separate step.
These articles can help guide you through integrating React Markdown into your project:
Reproduce The Issue
Before you jump to the solution, it is always better to reproduce any issue you encounter.
This approach helps you minimize clutter and locate the problem easier.
To reproduce the ReactMarkdown with Tailwind CSS issue, you can use this code:
import '@/styles/globals.css'; const AppHome: React.FC<{}> = () => { const markdown = ` # This is heading 1 ## This is heading 2 ### This is heading 3 #### This is heading 4 **Unordered List** - Apple - Orange - Avocado *Ordered List* 1. Bread 2. Milk 3. Cheese `; return <ReactMarkdown>{markdown}</ReactMarkdown>; }; export default AppHome;
Here is the breakdown of the above code:
- This line
import '@/styles/globals.css';
basically, it imports your CSS to use it within your page.
- You store markdown text in a
const markdown
variable.
- You pass the
markdown
variable as aReactMarkdown
child.
Notice that no styling is currently being applied.
You can open the development tools and inspect the generated HTML to verify its correctness.
<body> <h1>Hello This is Mozzlog</h1> <p><strong>Unordered List</strong></p> <pre><code>- Apple - Orange - Avocado *Ordered List* </code></pre> <ol> <li>Bread</li> <li>Milk</li> <li>Cheese</li> </ol> </body>
Something is missing, of course.
Why does React Markdown not display its styling?
The presence of Tailwind CSS is what makes React Markdown not work. This is the point of conflict.
To verify the accuracy of the above conflict statement, you can disable Tailwind CSS by removing or commenting out the import Tailwind CSS line.
You should see that React Markdown renders with appropriate styling.
// import '@/styles/global.css'; <-- this disable the Tailwind CSS
However, your project doesn’t need to remove Tailwind CSS in order to make ReactMarkdown work. And you should not.
Typically, your project introduces ReactMarkdown at some stage after Tailwind CSS has already been integrated throughout your codebase.
Removing Tailwind CSS means you are doing a lot of work for little gain.
You will learn how to fix the conflict in the next section.
Let’s make the the react markdown not working gone!
Resolving React Markdown Renderer and Tailwind CSS Not Working
The problem you need to address is that certain native Markdown elements don't render properly when Tailwind CSS is present. This is a significant issue.
First, you will fix the issue with the heading.
1. Problem With Headings h1
, h2
, and h3
This Markdown demonstrates headings such as
h1
, h2
, h3
, and others:# This is heading 1 ## This is heading 2 ### This is heading 3 #### This is heading 4 And you can see that it renders just like this paragraph element.
Using the Markdown component, you can pass it as a child:
const markdown = ` # This is heading 1 ## This is heading 2 ### This is heading 3 #### This is heading 4 And you can see that it renders just like this paragraph element. `; <ReactMarkdown>{markdown}</ReactMarkdown>;
The Heading Not Working Solution
To address this problem, you need to create a custom component to render heading and set styling with Tailwind CSS.
<ReactMarkdown components={{ h1: ({ node, ...props }) => ( <h1 className="font-bold text-6xl" {...props} /> ), }} >{markdown}</ReactMarkdown>
The above code can be described as follows:
- You create custom component for
h1
by returningh1
html element
- You pass
font-bold
andtext-6xl
to style theh1
element using TailwindCSS component
- You pass original props from ReactMarkdown to your custom component
You start to make Tailwind CSS work together with ReactMarkdown! Congratulations!
2. Problem with Lists ul
, ol
While headings pose a problem, you'll also encounter issues with lists.
**Unordered List** - Apple - Orange - Avocado *Ordered List* 1. Bread 2. Milk 3. Cheese
Which is not what you want. The actual markdown must display Unordered List items prefixed with a dot character, while Ordered List must render the respective numbers.
The List Not Working Solution
Similar to the heading solution, you need to implement a custom component to handle how lists are rendered in your
ReactMarkdown
, ensuring compatibility with Tailwind CSS.<ReactMarkdown components={{ ul: ({ node, ...props }) => ( <ul style={{ display: "block", listStyleType: "disc", paddingInlineStart: "40px", }} {...props} /> ), ol: ({ node, ...props }) => ( <ol style={{ display: "block", listStyleType: "decimal", paddingInlineStart: "40px", }} {...props} /> ), }} >{markdown}</ReactMarkdown>
The above code can be described as follows for the
ul
element:- You create custom component for
ul
by returningul
html element
- You pass custom style
listStyleType: disc
to makeul
render dot for itsli
children
- You pass original props from
ReactMarkdown
to your customul
component
The above code can be described as follows for the
ol
element:- You create custom component for
ol
by returningol
html element
- You pass custom style
listStyleType: decimal
to makeol
render dot for itsli
children
- You pass original props from
ReactMarkdown
to your customol
component
The Result
Now that you've resolved the conflict between React Markdown and Tailwind CSS with custom components, you can continue using Tailwind CSS alongside it.
To validate the fix, you can copy and paste this modified code into your project to see the results:
const markdown = ` # This is heading 1 ## This is heading 2 ### This is heading 3 #### This is heading 4 The heading must be displayed differently with this paragraph text. **Unordered List** - Apple - Orange - Avocado *Ordered List* 1. Bread 2. Milk 3. Cheese `; return <ReactMarkdown components={{ h1: ({ node, ...props }) => ( <h1 className="font-bold text-6xl" {...props} /> ), ul: ({ node, ...props }) => ( <ul style={{ display: "block", listStyleType: "disc", paddingInlineStart: "40px", }} {...props} /> ), ol: ({ node, ...props }) => ( <ol style={{ display: "block", listStyleType: "decimal", paddingInlineStart: "40px", }} {...props} /> ), }} >{markdown}</ReactMarkdown>;
Conclusion
And there you have it!
Fixing the
ReactMarkdown
and Tailwind CSS conflict seems hard at first, but it turns out the solution is simple and easy.Other than being easy, you also learn how to use the
ReactMarkdown
custom component, which opens many possibilities for rendering your markdown file more beautiful later.Where to Go From Here
After you have learned how to use
ReactMarkdown
custom components, it will be easier to make a custom render that displays the element in a way that was not easy before.Teaming up with Tailwind CSS, you can also build your beautiful custom component to the max
References
Reading this article is not complete if you don't check out another article that can help you understand more about React, Next.js, Tailwind CSS, and React-Markdown.
Go check out:
Keep exploring, and happy coding!