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 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>
CustomHorizontalRule
border-t
border-gray-300
my-6
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.