React.jsTailwindCSS
Last updated at 2023-10-28

React Markdown Custom Renderer with Tailwind CSS

ClickUp
Note
AI Status
Last Edit By
Last edited time
Oct 28, 2023 11:12 PM
Metatag
Slug
react-markdown-custom-renderer
Writer
Published
Published
Date
Oct 29, 2023
Category
React.js
TailwindCSS
Whether you are rendering a blog article or building a SaaS application that works with Text, Markdown plays an important role nowadays. There are many possibilites that you can do utilizing it to make your project succssfull.
In this article, you will learn how to render markdown elements using custom components so that it displays the element uniuqiely.

React Markdown conflict with Tailwind CSS

So just you know that before you learn how to write custom renderer for ReactMarkdown with tailwind css, you need to know that both tool has conflict.
Actually, when you use React markdown with tailwind css, the heading element and list element will not render properly.
This is bad. But offcourse there is a solution to every problem.
The solution is to render react markdown using custom component, the thing you will learn in this article.
However, it is better to understand how the conflict happen between React markdown and tailwind css.
You can read this article to learn more.

Custom Heading Renderer

Heading in markdown plays crucial role to structrue your content for readers. This element helps reader skim the content topics before finding motivation to continue delve deeper to the subject you write. Either h1, h2, h3, h4, h5, or h6, it is important to highlight main talking topic in this heading.
In this section you will learn to render custom heading component in React Markdown and style it using Tailwind CSS.

h1 Heading

A main element, usually title of your content should be rendered using h1 heading. This element serves as entry point for the reader.
Using React markdown custom component you can render h1 heading to create strong visual impact.
const CustomH1 = ({ children }) => ( <h1 className="text-3xl font-bold mb-4">{children}</h1> ); <ReactMarkdown components={{ h1: CustomH1, }} > {markdown} </ReactMarkdown>
In the example above, you create CustomH1 component to render h1 element and style it using Tailwind CSS text-3xl font-bold mb-4 class. The styling will create extra large text with bold font.

h2 to h6 Headings

Another important heading are h2 to h6. They provide hierarchical structure and further organizaton to your content.
Using custom component can render these elements for better readability and create cohesive design that represent your brand.
const CustomH2 = ({ children }) => ( <h2 className="text-2xl font-bold">{children}</h2> ); const CustomH3 = ({ children }) => ( <h3 className="text-xl font-bold">{children}</h3> ); const CustomH4 = ({ children }) => ( <h4 className="text-lg font-bold">{children}</h4> ); const CustomH5 = ({ children }) => ( <h5 className="text-base font-bold">{children}</h5> ); const CustomH6 = ({ children }) => ( <h6 className="text-sm font-bold">{children}</h6> ); <ReactMarkdown components={{ h2: CustomH2, h3: CustomH3, h4: CustomH4, h5: CustomH5, h6: CustomH6, }} > {markdown} </ReactMarkdown>
Using Tailwind CSS, you apply different style to each heading respectively. h2 is the biggest while h6 is the smallest. The font sizes are (text-2xl, text-xl, text-lg, text-base, text-sm). SImilar to h1 heading, you apply bold styling here.
A different text size can help reader by maintining visual consisten deisgn to represent clear hiearcy in the content. It also help readers to navigate and understand content structure.

Custom Paragraph Renderer

Paragraphs are a major component of markdown content. Because it takes up a significant portion of the content, you should render paragraphs in a visually appealing and readable manner to ensure that your message comes across effectively.

p Paragraph

Your brand may have different preference over default style provided by React Markdown.
To create a custom component to render the content paragraph, you can assign the paragrapm field in ReactMarkdown component.
const CustomParagraph = ({ children }) => ( <p className="text-gray-800 leading-relaxed mb-4">{children}</p> ); <ReactMarkdown components={{ p: CustomParagraph, }} > {markdown} </ReactMarkdown>
CustomParagraph apply customization by styling the paragraph text with text-gray-800 leading relaxed. This helps reader enjoy consuming texts becuase the color is soft to eye and visually cohesive.

Inline Elements within Paragraphs

A paragraph with emphasis, strong, links, and code snippet often requires different styling.
The code below creates custom component to handle emphasis, strong, links and code inside a paragraph.
const CustomParagraph = ({ children }) => ( <p className="text-gray-800 leading-relaxed mb-4"> {children} </p> ); const CustomEmphasis = ({ children }) => ( <em className="text-blue-500">{children}</em> ); const CustomStrong = ({ children }) => ( <strong className="text-red-500">{children}</strong> ); const CustomLink = ({ href, children }) => ( <a href={href} className="text-green-500 underline" target="_blank"> {children} </a> ); <ReactMarkdown components={{ p: CustomParagraph, em: CustomEmphasis, strong: CustomStrong, a: CustomLink, }} > {markdown} </ReactMarkdown>
em component is responsible to render emphasis (italic) element inside a paragraph.
strong component is responsible to render strong (bold) element inside a paragraph.
a component is responsible to render link element inside a paragraph.
This capability to customize each element allows you to apply more styling to the element such as differnt font, background color, or wrapp it with more advanced component.

Custom Link Renderer

LInking articles helps you maintain relation between them. This in SEO world, help Google to build profile about the topic around the article. A common practice is not to let an orphan article or article without link.

a Link

Some brands prefers to highlight links becuase it can help user navigate through pages.
This can reduce the visitor bounce rate becuase they staying with the pages for longer period.
const CustomLink = ({ href, children }) => ( <a href={href} className="text-blue-500 hover:underline hover:text-blue-600" target="_blank" rel="noopener noreferrer" > {children} </a> ); <ReactMarkdown components={{ a: CustomLink, }} > {markdown} </ReactMarkdown>
The custom component above sets the link color to text-blue-500 and when hovered it will display the link with underline with color text-blue-600. A target _blank attribute opens link in a new tab. The rel="noopener noreferrer" attribute adds security measures for external links.

Internal and External Links

For a blogger, promoting internal link over external link help the user visit much more pages rather than leave the website.
You can have different link style both for internal and external link that will help a increase page visit time and win the SEO.
const CustomInternalLink = ({ href, children }) => ( <a href={href} className="text-green-500 hover:underline hover:text-green-600" > {children} </a> ); const CustomExternalLink = ({ href, children }) => ( <a href={href} className="text-blue-500 hover:underline hover:text-blue-600" target="_blank" rel="noopener noreferrer" > {children} </a> ); <ReactMarkdown components={{ a: ({ href, children }) => { if (href.startsWith("#")) { return <CustomInternalLink href={href}>{children}</CustomInternalLink>; } else { return ( <CustomExternalLink href={href}>{children}</CustomExternalLink> ); } }, }} > {markdown} </ReactMarkdown>
They way you customize link style and differentiating internal and external link will improve the overal user experience. A user friendly reading experience should align with the purpose of the application/wbesite.
Different style for internal and external link helps user to notice that when they tap a link, it has different behavior.

Custom Image Renderer

Displaying images in a Markdown content is very important. By providing image, you basically help the reader with visaul context and readabliity.
It is much easire to digest text-image-text content steyl rather than consuming wall of text.
Customizing image rendering in RectMarkdown can be done using TailwindCSS. You will have the ability to display the image in visually pleasing and consisten manner.

Rendering Images

To customize the rendering of images, you can define a custom component that wraps the <img> element and applies desired styles.
You can also add captions or additional information alongside the images for improved context.
To add more styling capability when displaying image, you can wrap the image element using div like this component below.
const CustomImage = ({ alt, src, title }) => ( <div className="my-4"> <img className="max-w-full rounded-lg shadow-md" src={src} alt={alt} title={title} /> {title && <p className="text-center text-sm mt-2 text-gray-600">{title}</p>} </div> ); <ReactMarkdown components={{ img: CustomImage, }} > {markdown} </ReactMarkdown>
In the example above, the CustomImage component is defined to render images. The max-w-full class ensures that images do not exceed their original width, and the rounded-lg and shadow-md classes add styling for a rounded and shadowed appearance.
If an image has a title attribute, it's displayed as a caption below the image.

Customizing Image Styles

Tailwind CSS classes can be used to customize the appearance of images further. For instance, you can adjust the width, height, margins, and borders of images to match your design preferences.
const CustomImage = ({ alt, src, title }) => ( <div className="my-4"> <img className="max-w-full h-auto mx-auto rounded-lg shadow-md border-2 border-gray-300" src={src} alt={alt} title={title} /> {title && <p className="text-center text-sm mt-2 text-gray-600">{title}</p>} </div> ); <ReactMarkdown components={{ img: CustomImage, }} > {markdown} </ReactMarkdown>
In the updated code, the h-auto class maintains the image's aspect ratio, the mx-auto class centers the image horizontally, and the border-2 and border-gray-300 classes add a subtle border around the image.
The styling code above will add border color and round each corner of the image. If you put image in grid, a border can help make each image distict from each other.
By customizing the rendering and styles of images, you can enhance the visual presentation of your content and create a more engaging reading experience.
Adjust the Tailwind CSS classes and attributes to match your desired image styling and overall design.

Custom Block Quotes Renderer

A block quote is commonly used when the content need to quote a text from another source.
Customizing the rendering block quotes can be done using a custom component using Tailwind CSS to style it.
It actully depends on how you brands want to display a block quotes. Regardless the goal, here is how you can render custom component block quote.

Rendering Block Quotes

To customize blockquote, you can use blockquote html element.
const CustomBlockQuote = ({ children }) => ( <blockquote className="bg-gray-100 border-l-4 border-blue-500 px-4 py-3 my-4"> {children} </blockquote> ); <ReactMarkdown components={{ blockquote: CustomBlockQuote, }} > {markdown} </ReactMarkdown>
In the example above, the CustomBlockQuote component is defined to render block quotes.
The bg-gray-100 class gives the block quote a light gray background, the border-l-4 and border-blue-500 classes add a blue border on the left side, and the px-4 and py-3 classes add padding to the block quote.

Customizing Block Quote Styles

You can use Tailwind CSS classes to further customize the appearance of block quotes to match your design preferences.
If you want to display the blockquote with different line color, you can use tailwind css blockquote styling classes.
const CustomBlockQuote = ({ children }) => ( <blockquote className="bg-gray-200 border-l-4 border-blue-600 px-6 py-4 my-6 text-lg italic"> {children} </blockquote> ); <ReactMarkdown components={{ blockquote: CustomBlockQuote, }} > {markdown} </ReactMarkdown>
In the updated code, the bg-gray-200 class changes the background color of the block quote, the border-l-4 and border-blue-600 classes alter the border color, the px-6 and py-4 classes add more padding for increased spacing, and the text-lg and italic classes style the quoted text.
By customizing the rendering and styles of block quotes, you can make them stand out and visually separate them from the surrounding content.
Modify the Tailwind CSS classes and attributes to create the desired look for block quotes in your content.

Custom Code Blocks Renderer

Code blocks are a crucial part of technical content, as they allow you to present and explain code examples to your readers.
With react-markdown and Tailwind CSS, you can customize the styling of code blocks to make them visually appealing and easy to read.
In this section, you'll learn how to create custom rendering for code blocks.

Rendering Code Blocks

Usually, code block are rendered using code html element.
If you use Custom renderer, you can wrap it using div element and add styling it.
const CustomCodeBlock = ({ language, value }) => ( <pre className="bg-gray-900 text-white p-4 rounded-lg"> <code className={`language-${language}`}>{value}</code> </pre> ); <ReactMarkdown components={{ code: CustomCodeBlock, }} > {markdown} </ReactMarkdown>
In the example above, the CustomCodeBlock component is defined to render code blocks.
The bg-gray-900 class gives the code block a dark background color, the text-white class sets the text color to white, and the p-4 and rounded-lg classes add padding and rounded corners to the code block.
The inner code element uses the specified language class for syntax highlighting.

Customizing Code Block Styles

Different language has different style and sometimes your visitor also prefers specific theme for the code such as darcula or Xcode. You can use Syntax Higlighter with HLJS or PrismJs to show code in user prefered style.
const CustomCodeBlock = ({ language, value }) => ( <pre className="bg-gray-800 text-gray-200 p-6 rounded-md"> <code className={`language-${language}`}>{value}</code> </pre> ); <ReactMarkdown components={{ code: CustomCodeBlock, }} > {markdown} </ReactMarkdown>
In the updated code, the bg-gray-800 class changes the background color of the code block, the text-gray-200 class alters the text color, and the p-6 and rounded-md classes enhance padding and rounded corners for better readability.

Discussion (0)

Related Posts