React-markdown: Classes for individual elements

Created on 13 Jul 2017  路  11Comments  路  Source: remarkjs/react-markdown

Would it be possible to apply individual classes to the elements generated by react-markdown? This would make it possible to style the page using libraries such as Bootstrap or Bulma.

Most helpful comment

"Nothing happened" is a bit short on information.

Here's a basic example:

function Link(props) {
  return <a href={props.href} className="my-link-class">{props.children}</a>
}

function BlockQuote(props) {
  return <blockquote className="my-block-quote">{props.children}</blockquote>
}

<ReactMarkdown
  source="> What's the URL to your website?\n\nIt's at [espen.codes](https://espen.codes/)."
  renderers={{Link: Link, BlockQuote: BlockQuote}}
/>

All 11 comments

It looks to me like you could achieve this by specifying a renderers object which defined each of the node type as a react component that was essentially the vanilla node with your class applied.

I see. Is there an example somewhere of how this works? I passed in my own renderers object into the react-markdown component but nothing happened.

"Nothing happened" is a bit short on information.

Here's a basic example:

function Link(props) {
  return <a href={props.href} className="my-link-class">{props.children}</a>
}

function BlockQuote(props) {
  return <blockquote className="my-block-quote">{props.children}</blockquote>
}

<ReactMarkdown
  source="> What's the URL to your website?\n\nIt's at [espen.codes](https://espen.codes/)."
  renderers={{Link: Link, BlockQuote: BlockQuote}}
/>

This does somehow not work for me. The renderer function i not invoked

@neilyoung Would you be able to share a minimal example of your code which is not behaving as expected?

@captbaritone Thanks for the feedback. Meanwhile I found the reason for this "not found": It is case sensitive. In fact the correct renderers would need to be addressed with lowercase keys (which corresponds to the renderers documentation), like so for example:

<ReactMarkdown source={about} renderers={{
                        table: (props) => {
                            return <table className="mdTable">{props.children}</table>
                        }
                    }}></ReactMarkdown> 

The important thing is the correct case of the key. And CSS classes should exist of course.

So the corrected example above would look like:

<ReactMarkdown
  source="> What's the URL to your website?\n\nIt's at [espen.codes](https://espen.codes/)."
  renderers={link: Link, blockquote: BlockQuote}}
/>

This was really useful to me. I use a CSS framework called Bulma and it wants classes like:

<h1 class="title is-1">

and

<h2 class="title is-2>

etc.

I achieved this with:

function Heading(props) {
  const level = props.level;
  const tagName = `h${level}`;
  return React.createElement(
    tagName, { className: `title is-${level}` },
    props.children
  );
}

const bulmaRenderer = {
  heading: Heading
}

But it would have been cool to have something in the README.md about how this works. The current description of how renderers works, and which props you can access for each type is a little unclear.

@roblevy for Bulma you can simply use

<ReactMarkdown className="content" source={text} />

https://bulma.io/documentation/elements/content/

@shicholas what u wrote will give a class to the container, not the child

Based on @rexxars answer but updated for 2020 & TypeScript with the following changes

  • Using React.forwardRef to forward the ref, in case you want to render for example a Material-UI Tooltip on it.
  • Added TypeScript types
  • Fixed the renderer prop on the component (link is now lowercased, instead of titlecased)
// Link.tsx
import React, { forwardRef } from 'react';

interface LinkProps {
    href: string;
}

export default forwardRef<HTMLLinkElement, LinkProps>(props => {
    return (
        <a href={props.href} className="my-link-class">
            {props.children}
        </a>
    );
});
// where you use ReactMarkdown
<ReactMarkdown
    source="Demo available at [rexxars.github.io](https://rexxars.github.io/react-markdown/)"
    skipHtml
    parserOptions={{ gfm: true }}
    renderers={{ link: Link }}
/>
Was this page helpful?
0 / 5 - 0 ratings