How can I replace Markdown-rendered HTML tags with React components?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















At the moment, I'm converting the Markdown to HTML code using marked, then I replace some parts of it with React elements. This results in an array of HTML strings and React elements, which can be rendered indeed:



const prepareGuide = markdown => replaceToArray(
marked(markdown),
/<a href="SOME_SPECIAL_HREF".*?>(.*?)</a>/,
(match, label, slug) => <a href={`/${slug}`}>{label}</a>
)

const Guide = ({ guide }) =>
prepareGuide(guide.fields.text).map(
n => typeof n === 'object'
? n
: <span dangerouslySetInnerHTML={{ __html: n }} />
)


The problem with this, let's just call it workaround, is that every piece of HTML needs a wrapper element, like span (and uses dangerouslySetInnerHTML).



What I basically need is the ability to replace the rendered HTML elements with React components to add React functionality like Router links and other, custom elements.



Any other approaches?



Edit: The replaceToArray function I used is like String.prototype.replace, but returns an array (so any type can be returned)



Edit: Another approach I had was to render the HTML directly to the DOM (using dangerouslySetInnerHTML), and using the container element's ref to query all elements I want to replace. But, next problem: To render React components inside the HTML ref I have, I'd need another React root, which is possible, but unpractical, because I'd lose all the contexts (like Router), so I can't even properly use Router Links that way.










share|improve this question




















  • 1





    maybe have a look at github.com/rexxars/commonmark-react-renderer

    – mb21
    Jan 8 '18 at 13:41


















0















At the moment, I'm converting the Markdown to HTML code using marked, then I replace some parts of it with React elements. This results in an array of HTML strings and React elements, which can be rendered indeed:



const prepareGuide = markdown => replaceToArray(
marked(markdown),
/<a href="SOME_SPECIAL_HREF".*?>(.*?)</a>/,
(match, label, slug) => <a href={`/${slug}`}>{label}</a>
)

const Guide = ({ guide }) =>
prepareGuide(guide.fields.text).map(
n => typeof n === 'object'
? n
: <span dangerouslySetInnerHTML={{ __html: n }} />
)


The problem with this, let's just call it workaround, is that every piece of HTML needs a wrapper element, like span (and uses dangerouslySetInnerHTML).



What I basically need is the ability to replace the rendered HTML elements with React components to add React functionality like Router links and other, custom elements.



Any other approaches?



Edit: The replaceToArray function I used is like String.prototype.replace, but returns an array (so any type can be returned)



Edit: Another approach I had was to render the HTML directly to the DOM (using dangerouslySetInnerHTML), and using the container element's ref to query all elements I want to replace. But, next problem: To render React components inside the HTML ref I have, I'd need another React root, which is possible, but unpractical, because I'd lose all the contexts (like Router), so I can't even properly use Router Links that way.










share|improve this question




















  • 1





    maybe have a look at github.com/rexxars/commonmark-react-renderer

    – mb21
    Jan 8 '18 at 13:41














0












0








0








At the moment, I'm converting the Markdown to HTML code using marked, then I replace some parts of it with React elements. This results in an array of HTML strings and React elements, which can be rendered indeed:



const prepareGuide = markdown => replaceToArray(
marked(markdown),
/<a href="SOME_SPECIAL_HREF".*?>(.*?)</a>/,
(match, label, slug) => <a href={`/${slug}`}>{label}</a>
)

const Guide = ({ guide }) =>
prepareGuide(guide.fields.text).map(
n => typeof n === 'object'
? n
: <span dangerouslySetInnerHTML={{ __html: n }} />
)


The problem with this, let's just call it workaround, is that every piece of HTML needs a wrapper element, like span (and uses dangerouslySetInnerHTML).



What I basically need is the ability to replace the rendered HTML elements with React components to add React functionality like Router links and other, custom elements.



Any other approaches?



Edit: The replaceToArray function I used is like String.prototype.replace, but returns an array (so any type can be returned)



Edit: Another approach I had was to render the HTML directly to the DOM (using dangerouslySetInnerHTML), and using the container element's ref to query all elements I want to replace. But, next problem: To render React components inside the HTML ref I have, I'd need another React root, which is possible, but unpractical, because I'd lose all the contexts (like Router), so I can't even properly use Router Links that way.










share|improve this question
















At the moment, I'm converting the Markdown to HTML code using marked, then I replace some parts of it with React elements. This results in an array of HTML strings and React elements, which can be rendered indeed:



const prepareGuide = markdown => replaceToArray(
marked(markdown),
/<a href="SOME_SPECIAL_HREF".*?>(.*?)</a>/,
(match, label, slug) => <a href={`/${slug}`}>{label}</a>
)

const Guide = ({ guide }) =>
prepareGuide(guide.fields.text).map(
n => typeof n === 'object'
? n
: <span dangerouslySetInnerHTML={{ __html: n }} />
)


The problem with this, let's just call it workaround, is that every piece of HTML needs a wrapper element, like span (and uses dangerouslySetInnerHTML).



What I basically need is the ability to replace the rendered HTML elements with React components to add React functionality like Router links and other, custom elements.



Any other approaches?



Edit: The replaceToArray function I used is like String.prototype.replace, but returns an array (so any type can be returned)



Edit: Another approach I had was to render the HTML directly to the DOM (using dangerouslySetInnerHTML), and using the container element's ref to query all elements I want to replace. But, next problem: To render React components inside the HTML ref I have, I'd need another React root, which is possible, but unpractical, because I'd lose all the contexts (like Router), so I can't even properly use Router Links that way.







reactjs markdown






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 7 '18 at 19:11







22samuelk

















asked Jan 7 '18 at 18:55









22samuelk22samuelk

4031417




4031417








  • 1





    maybe have a look at github.com/rexxars/commonmark-react-renderer

    – mb21
    Jan 8 '18 at 13:41














  • 1





    maybe have a look at github.com/rexxars/commonmark-react-renderer

    – mb21
    Jan 8 '18 at 13:41








1




1





maybe have a look at github.com/rexxars/commonmark-react-renderer

– mb21
Jan 8 '18 at 13:41





maybe have a look at github.com/rexxars/commonmark-react-renderer

– mb21
Jan 8 '18 at 13:41












2 Answers
2






active

oldest

votes


















0














I was able to solve this as follows:



I kept using marked and dangerouslySetInnerHTML to directly set the HTML. Now, as described in the second approach, I used the ref to query the elements I want to replace. Now to be able to render React elements to the HTML, I just used the ReactDOM.render function.



The biggest problem with this was that components didn't have access to the app's context, since I now had multiple React roots. To solve this, I figured out that we can copy the context from one component to another: Is it possible to pass context into a component instantiated with ReactDOM.render?



So to be able to access the context in the component that renders the HTML, we need to set the component's contextTypes for the contexts we need to copy.



class Article extends Component {
static contextTypes = {
router: PropTypes.any
}

static propTypes = {
markdown: PropTypes.string
}

prepare(ref) {
const Provider = createContextProvider(this.context)
const links = Array.from(ref.querySelectorAll('a'))

links.forEach((link) => {
const span = document.createElement('span')
const { pathname } = url.parse(link.href)
const text = link.innerText

link.parentNode.replaceChild(span, link)
ReactDOM.render(
<Provider>
<Link to={pathname}>{text}</Link>
</Provider>,
span
)
})
}

render() {
return (
<article
ref={this.prepare}
dangerouslySetInnerHTML={{ __html: marked(this.props.markdown) }}
/>
)
}
}


The above code requires the snipped which I copied from the question linked above. The method I called prepare replaces specific HTML nodes with React roots.



function createContextProvider(context) {
class ContextProvider extends React.Component {
getChildContext() {
return context
}

render = () => this.props.children

static propTypes = { children: PropTypes.node }
}

ContextProvider.childContextTypes = {}
Object.keys(context).forEach(key => {
ContextProvider.childContextTypes[key] = PropTypes.any.isRequired
})

return ContextProvider
}


So we basically have a function that creates a Provider component. That function needs to be able to dynamically adapt to the required context types, that's why the loop sets them to be required.






share|improve this answer

































    0














    If you simply want to have links work with React Router, you can render the markdown as usual with dangerouslySetInnerHTML then intercept internal link clicks to make them go through react-router.



    Full example of loading .md externally, then catching links to process with react-router:



    import React from "react"
    import { withRouter } from 'react-router'

    import catchLinks from 'catch-links'
    import marked from "marked"

    import styles from './styles.scss'

    class ContentPage extends React.Component {

    constructor(props) {
    super(props);
    this.state = {
    loading: false,
    markdown: '',
    title: ''
    }
    }

    componentDidMount() {

    if (typeof window !== 'undefined') {
    catchLinks(window, (href) => {
    this.props.history.push(href);
    });
    }

    const page = location.pathname.replace('/', '');

    fetch(`/assets/content/${page}.md`)
    .then(response => response.text())
    .then(text => {
    this.setState({ markdown: marked(text, {}) })
    });

    const title = page_titles[page] || capitalize(page);

    if (title) {
    document.title = title;
    this.setState({title})
    }

    }

    render() {

    const {
    markdown,
    title
    } = this.state;

    return (
    <div class={styles.contentPage}>

    <div class={styles.pageTop}>
    {title}
    </div>

    <div class={styles.page}>
    <div class={styles.content} dangerouslySetInnerHTML={{__html: markdown}}></div>
    </div>

    </div>
    );
    }
    }

    export default withRouter(ContentPage);





    share|improve this answer
























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48140505%2fhow-can-i-replace-markdown-rendered-html-tags-with-react-components%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      I was able to solve this as follows:



      I kept using marked and dangerouslySetInnerHTML to directly set the HTML. Now, as described in the second approach, I used the ref to query the elements I want to replace. Now to be able to render React elements to the HTML, I just used the ReactDOM.render function.



      The biggest problem with this was that components didn't have access to the app's context, since I now had multiple React roots. To solve this, I figured out that we can copy the context from one component to another: Is it possible to pass context into a component instantiated with ReactDOM.render?



      So to be able to access the context in the component that renders the HTML, we need to set the component's contextTypes for the contexts we need to copy.



      class Article extends Component {
      static contextTypes = {
      router: PropTypes.any
      }

      static propTypes = {
      markdown: PropTypes.string
      }

      prepare(ref) {
      const Provider = createContextProvider(this.context)
      const links = Array.from(ref.querySelectorAll('a'))

      links.forEach((link) => {
      const span = document.createElement('span')
      const { pathname } = url.parse(link.href)
      const text = link.innerText

      link.parentNode.replaceChild(span, link)
      ReactDOM.render(
      <Provider>
      <Link to={pathname}>{text}</Link>
      </Provider>,
      span
      )
      })
      }

      render() {
      return (
      <article
      ref={this.prepare}
      dangerouslySetInnerHTML={{ __html: marked(this.props.markdown) }}
      />
      )
      }
      }


      The above code requires the snipped which I copied from the question linked above. The method I called prepare replaces specific HTML nodes with React roots.



      function createContextProvider(context) {
      class ContextProvider extends React.Component {
      getChildContext() {
      return context
      }

      render = () => this.props.children

      static propTypes = { children: PropTypes.node }
      }

      ContextProvider.childContextTypes = {}
      Object.keys(context).forEach(key => {
      ContextProvider.childContextTypes[key] = PropTypes.any.isRequired
      })

      return ContextProvider
      }


      So we basically have a function that creates a Provider component. That function needs to be able to dynamically adapt to the required context types, that's why the loop sets them to be required.






      share|improve this answer






























        0














        I was able to solve this as follows:



        I kept using marked and dangerouslySetInnerHTML to directly set the HTML. Now, as described in the second approach, I used the ref to query the elements I want to replace. Now to be able to render React elements to the HTML, I just used the ReactDOM.render function.



        The biggest problem with this was that components didn't have access to the app's context, since I now had multiple React roots. To solve this, I figured out that we can copy the context from one component to another: Is it possible to pass context into a component instantiated with ReactDOM.render?



        So to be able to access the context in the component that renders the HTML, we need to set the component's contextTypes for the contexts we need to copy.



        class Article extends Component {
        static contextTypes = {
        router: PropTypes.any
        }

        static propTypes = {
        markdown: PropTypes.string
        }

        prepare(ref) {
        const Provider = createContextProvider(this.context)
        const links = Array.from(ref.querySelectorAll('a'))

        links.forEach((link) => {
        const span = document.createElement('span')
        const { pathname } = url.parse(link.href)
        const text = link.innerText

        link.parentNode.replaceChild(span, link)
        ReactDOM.render(
        <Provider>
        <Link to={pathname}>{text}</Link>
        </Provider>,
        span
        )
        })
        }

        render() {
        return (
        <article
        ref={this.prepare}
        dangerouslySetInnerHTML={{ __html: marked(this.props.markdown) }}
        />
        )
        }
        }


        The above code requires the snipped which I copied from the question linked above. The method I called prepare replaces specific HTML nodes with React roots.



        function createContextProvider(context) {
        class ContextProvider extends React.Component {
        getChildContext() {
        return context
        }

        render = () => this.props.children

        static propTypes = { children: PropTypes.node }
        }

        ContextProvider.childContextTypes = {}
        Object.keys(context).forEach(key => {
        ContextProvider.childContextTypes[key] = PropTypes.any.isRequired
        })

        return ContextProvider
        }


        So we basically have a function that creates a Provider component. That function needs to be able to dynamically adapt to the required context types, that's why the loop sets them to be required.






        share|improve this answer




























          0












          0








          0







          I was able to solve this as follows:



          I kept using marked and dangerouslySetInnerHTML to directly set the HTML. Now, as described in the second approach, I used the ref to query the elements I want to replace. Now to be able to render React elements to the HTML, I just used the ReactDOM.render function.



          The biggest problem with this was that components didn't have access to the app's context, since I now had multiple React roots. To solve this, I figured out that we can copy the context from one component to another: Is it possible to pass context into a component instantiated with ReactDOM.render?



          So to be able to access the context in the component that renders the HTML, we need to set the component's contextTypes for the contexts we need to copy.



          class Article extends Component {
          static contextTypes = {
          router: PropTypes.any
          }

          static propTypes = {
          markdown: PropTypes.string
          }

          prepare(ref) {
          const Provider = createContextProvider(this.context)
          const links = Array.from(ref.querySelectorAll('a'))

          links.forEach((link) => {
          const span = document.createElement('span')
          const { pathname } = url.parse(link.href)
          const text = link.innerText

          link.parentNode.replaceChild(span, link)
          ReactDOM.render(
          <Provider>
          <Link to={pathname}>{text}</Link>
          </Provider>,
          span
          )
          })
          }

          render() {
          return (
          <article
          ref={this.prepare}
          dangerouslySetInnerHTML={{ __html: marked(this.props.markdown) }}
          />
          )
          }
          }


          The above code requires the snipped which I copied from the question linked above. The method I called prepare replaces specific HTML nodes with React roots.



          function createContextProvider(context) {
          class ContextProvider extends React.Component {
          getChildContext() {
          return context
          }

          render = () => this.props.children

          static propTypes = { children: PropTypes.node }
          }

          ContextProvider.childContextTypes = {}
          Object.keys(context).forEach(key => {
          ContextProvider.childContextTypes[key] = PropTypes.any.isRequired
          })

          return ContextProvider
          }


          So we basically have a function that creates a Provider component. That function needs to be able to dynamically adapt to the required context types, that's why the loop sets them to be required.






          share|improve this answer















          I was able to solve this as follows:



          I kept using marked and dangerouslySetInnerHTML to directly set the HTML. Now, as described in the second approach, I used the ref to query the elements I want to replace. Now to be able to render React elements to the HTML, I just used the ReactDOM.render function.



          The biggest problem with this was that components didn't have access to the app's context, since I now had multiple React roots. To solve this, I figured out that we can copy the context from one component to another: Is it possible to pass context into a component instantiated with ReactDOM.render?



          So to be able to access the context in the component that renders the HTML, we need to set the component's contextTypes for the contexts we need to copy.



          class Article extends Component {
          static contextTypes = {
          router: PropTypes.any
          }

          static propTypes = {
          markdown: PropTypes.string
          }

          prepare(ref) {
          const Provider = createContextProvider(this.context)
          const links = Array.from(ref.querySelectorAll('a'))

          links.forEach((link) => {
          const span = document.createElement('span')
          const { pathname } = url.parse(link.href)
          const text = link.innerText

          link.parentNode.replaceChild(span, link)
          ReactDOM.render(
          <Provider>
          <Link to={pathname}>{text}</Link>
          </Provider>,
          span
          )
          })
          }

          render() {
          return (
          <article
          ref={this.prepare}
          dangerouslySetInnerHTML={{ __html: marked(this.props.markdown) }}
          />
          )
          }
          }


          The above code requires the snipped which I copied from the question linked above. The method I called prepare replaces specific HTML nodes with React roots.



          function createContextProvider(context) {
          class ContextProvider extends React.Component {
          getChildContext() {
          return context
          }

          render = () => this.props.children

          static propTypes = { children: PropTypes.node }
          }

          ContextProvider.childContextTypes = {}
          Object.keys(context).forEach(key => {
          ContextProvider.childContextTypes[key] = PropTypes.any.isRequired
          })

          return ContextProvider
          }


          So we basically have a function that creates a Provider component. That function needs to be able to dynamically adapt to the required context types, that's why the loop sets them to be required.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 8 '18 at 21:13

























          answered Jan 8 '18 at 19:08









          22samuelk22samuelk

          4031417




          4031417

























              0














              If you simply want to have links work with React Router, you can render the markdown as usual with dangerouslySetInnerHTML then intercept internal link clicks to make them go through react-router.



              Full example of loading .md externally, then catching links to process with react-router:



              import React from "react"
              import { withRouter } from 'react-router'

              import catchLinks from 'catch-links'
              import marked from "marked"

              import styles from './styles.scss'

              class ContentPage extends React.Component {

              constructor(props) {
              super(props);
              this.state = {
              loading: false,
              markdown: '',
              title: ''
              }
              }

              componentDidMount() {

              if (typeof window !== 'undefined') {
              catchLinks(window, (href) => {
              this.props.history.push(href);
              });
              }

              const page = location.pathname.replace('/', '');

              fetch(`/assets/content/${page}.md`)
              .then(response => response.text())
              .then(text => {
              this.setState({ markdown: marked(text, {}) })
              });

              const title = page_titles[page] || capitalize(page);

              if (title) {
              document.title = title;
              this.setState({title})
              }

              }

              render() {

              const {
              markdown,
              title
              } = this.state;

              return (
              <div class={styles.contentPage}>

              <div class={styles.pageTop}>
              {title}
              </div>

              <div class={styles.page}>
              <div class={styles.content} dangerouslySetInnerHTML={{__html: markdown}}></div>
              </div>

              </div>
              );
              }
              }

              export default withRouter(ContentPage);





              share|improve this answer




























                0














                If you simply want to have links work with React Router, you can render the markdown as usual with dangerouslySetInnerHTML then intercept internal link clicks to make them go through react-router.



                Full example of loading .md externally, then catching links to process with react-router:



                import React from "react"
                import { withRouter } from 'react-router'

                import catchLinks from 'catch-links'
                import marked from "marked"

                import styles from './styles.scss'

                class ContentPage extends React.Component {

                constructor(props) {
                super(props);
                this.state = {
                loading: false,
                markdown: '',
                title: ''
                }
                }

                componentDidMount() {

                if (typeof window !== 'undefined') {
                catchLinks(window, (href) => {
                this.props.history.push(href);
                });
                }

                const page = location.pathname.replace('/', '');

                fetch(`/assets/content/${page}.md`)
                .then(response => response.text())
                .then(text => {
                this.setState({ markdown: marked(text, {}) })
                });

                const title = page_titles[page] || capitalize(page);

                if (title) {
                document.title = title;
                this.setState({title})
                }

                }

                render() {

                const {
                markdown,
                title
                } = this.state;

                return (
                <div class={styles.contentPage}>

                <div class={styles.pageTop}>
                {title}
                </div>

                <div class={styles.page}>
                <div class={styles.content} dangerouslySetInnerHTML={{__html: markdown}}></div>
                </div>

                </div>
                );
                }
                }

                export default withRouter(ContentPage);





                share|improve this answer


























                  0












                  0








                  0







                  If you simply want to have links work with React Router, you can render the markdown as usual with dangerouslySetInnerHTML then intercept internal link clicks to make them go through react-router.



                  Full example of loading .md externally, then catching links to process with react-router:



                  import React from "react"
                  import { withRouter } from 'react-router'

                  import catchLinks from 'catch-links'
                  import marked from "marked"

                  import styles from './styles.scss'

                  class ContentPage extends React.Component {

                  constructor(props) {
                  super(props);
                  this.state = {
                  loading: false,
                  markdown: '',
                  title: ''
                  }
                  }

                  componentDidMount() {

                  if (typeof window !== 'undefined') {
                  catchLinks(window, (href) => {
                  this.props.history.push(href);
                  });
                  }

                  const page = location.pathname.replace('/', '');

                  fetch(`/assets/content/${page}.md`)
                  .then(response => response.text())
                  .then(text => {
                  this.setState({ markdown: marked(text, {}) })
                  });

                  const title = page_titles[page] || capitalize(page);

                  if (title) {
                  document.title = title;
                  this.setState({title})
                  }

                  }

                  render() {

                  const {
                  markdown,
                  title
                  } = this.state;

                  return (
                  <div class={styles.contentPage}>

                  <div class={styles.pageTop}>
                  {title}
                  </div>

                  <div class={styles.page}>
                  <div class={styles.content} dangerouslySetInnerHTML={{__html: markdown}}></div>
                  </div>

                  </div>
                  );
                  }
                  }

                  export default withRouter(ContentPage);





                  share|improve this answer













                  If you simply want to have links work with React Router, you can render the markdown as usual with dangerouslySetInnerHTML then intercept internal link clicks to make them go through react-router.



                  Full example of loading .md externally, then catching links to process with react-router:



                  import React from "react"
                  import { withRouter } from 'react-router'

                  import catchLinks from 'catch-links'
                  import marked from "marked"

                  import styles from './styles.scss'

                  class ContentPage extends React.Component {

                  constructor(props) {
                  super(props);
                  this.state = {
                  loading: false,
                  markdown: '',
                  title: ''
                  }
                  }

                  componentDidMount() {

                  if (typeof window !== 'undefined') {
                  catchLinks(window, (href) => {
                  this.props.history.push(href);
                  });
                  }

                  const page = location.pathname.replace('/', '');

                  fetch(`/assets/content/${page}.md`)
                  .then(response => response.text())
                  .then(text => {
                  this.setState({ markdown: marked(text, {}) })
                  });

                  const title = page_titles[page] || capitalize(page);

                  if (title) {
                  document.title = title;
                  this.setState({title})
                  }

                  }

                  render() {

                  const {
                  markdown,
                  title
                  } = this.state;

                  return (
                  <div class={styles.contentPage}>

                  <div class={styles.pageTop}>
                  {title}
                  </div>

                  <div class={styles.page}>
                  <div class={styles.content} dangerouslySetInnerHTML={{__html: markdown}}></div>
                  </div>

                  </div>
                  );
                  }
                  }

                  export default withRouter(ContentPage);






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 3 at 4:56









                  Jack NichlausJack Nichlaus

                  1




                  1






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48140505%2fhow-can-i-replace-markdown-rendered-html-tags-with-react-components%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      MongoDB - Not Authorized To Execute Command

                      How to fix TextFormField cause rebuild widget in Flutter

                      Npm cannot find a required file even through it is in the searched directory