React.jsTailwindCSS
Last updated at 2023-10-29

React Markdown Custom Renderer with Tailwind CSS

ClickUp
Note
AI Status
Last Edit By
Last edited time
Oct 29, 2023 06:12 AM
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.
By customizing the rendering and styles of code blocks, you can make your code examples visually appealing and align them with the overall design of your content.
Adjust the Tailwind CSS classes and attributes to achieve the desired appearance for code blocks in your articles.

Custom Horizontal Rules Renderer

Horizontal rules, also known as divider lines or separators, are used to visually separate content within your markdown articles. With react-markdown and Tailwind CSS, you can customize the styling of horizontal rules to match the design of your website or application. In this section, you'll learn how to create custom rendering for horizontal rules.

Rendering Horizontal Rules

To customize the rendering of horizontal rules, you can define a custom component that applies desired styles to the divider line.
To render horizontal rules, you use hr html element.
const CustomHorizontalRule = () => ( <hr className="border-t border-gray-300 my-6" /> ); <ReactMarkdown components={{ thematicBreak: CustomHorizontalRule, }} > {markdown} </ReactMarkdown>
In the example above, the CustomHorizontalRule component is defined to render horizontal rules. The border-t class adds a top border to the rule, and the border-gray-300 class sets the border color. The my-6 class adds vertical margin to give the rule some spacing.

Customizing Horizontal Rule Styles

You can leverage Tailwind CSS classes to further customize the appearance of horizontal rules to match your design preferences.
const CustomHorizontalRule = () => ( <hr className="border-t-2 border-blue-500 my-8" /> ); <ReactMarkdown components={{ thematicBreak: CustomHorizontalRule, }} > {markdown} </ReactMarkdown>
In the updated code, the border-t-2 class increases the thickness of the top border of the rule, and the border-blue-500 class changes the border color to blue.
The my-8 class adds more vertical margin for enhanced separation.
By customizing the rendering and styles of horizontal rules, you can effectively define visual boundaries between sections of your content.
Adjust the Tailwind CSS classes and attributes to achieve the desired appearance for horizontal rules in your articles.

Custom Table Renderer

Tables are essential for presenting tabular data in a structured manner. With react-markdown and Tailwind CSS, you can style tables to match the overall design of your website or application. In this section, you'll learn how to create custom rendering for tables and apply styling to make them visually appealing.

Rendering Tables

To style tables, you can define a custom component that applies desired styles to the table elements.
Creating custom TableRendere can be done using table html element.
const CustomTable = ({ children }) => ( <div className="overflow-x-auto"> <table className="table-auto border-collapse border border-gray-300"> {children} </table> </div> ); <ReactMarkdown components={{ table: CustomTable, }} > {markdown} </ReactMarkdown>
In the example above, the CustomTable component wraps the table within a container with horizontal scrolling (overflow-x-auto) to handle overflow on smaller screens.
The table-auto class ensures that the table automatically sizes columns based on the content, and the border-collapse class collapses table borders.

Styling Table Rows and Cells

You can use Tailwind CSS classes to style table rows (tr) and cells (td) to enhance the visual presentation of your tables.
Styling the table can be done using tailwind. You can make the border red. Table without boder, the cell color, and so on.
const CustomTable = ({ children }) => ( <div className="overflow-x-auto"> <table className="table-auto border-collapse border border-gray-300"> {children} </table> </div> ); const CustomTableRow = ({ children }) => ( <tr className="bg-gray-100 border-b border-gray-300">{children}</tr> ); const CustomTableCell = ({ children }) => ( <td className="p-4 border border-gray-300">{children}</td> ); <ReactMarkdown components={{ table: CustomTable, tr: CustomTableRow, td: CustomTableCell, }} > {markdown} </ReactMarkdown>
In the code above, the CustomTableRow component applies a gray background and bottom border to table rows, while the CustomTableCell component adds padding and borders to table cells.

Applying Styles to Table Headers

As table has header, you can also apply specific styling to the header to differentiate them from regular cells. You can use th html element to render table header.
const CustomTableHeader = ({ children }) => ( <th className="p-4 border border-gray-300 bg-gray-200 font-semibold"> {children} </th> ); <ReactMarkdown components={{ th: CustomTableHeader, }} > {markdown} </ReactMarkdown>
The CustomTableHeader component adds a gray background, bold font weight, and borders to table headers.
By creating custom components and applying Tailwind CSS classes, you can easily style tables to make them visually appealing and well-structured. Adjust the classes and styles to align with your design preferences and overall website aesthetics.

Conclusion

There are a lot of customization can be done when you aim to use ReactMarkdown custom renderer using tailwind css.
You can make custom renderer and style them differently from the default implementation using react markdown custom component with tailwind css.
Using raect markdown custom component, you can start working to implement appealing and fresh design to make the user interface more beautiful.

Where to go from here

Reference

Discussion (0)

Related Posts