Accepted answer

You could leverage the html-to-react npm module.

Note: I'm the author of the module and just published it a few hours ago. Please feel free to report any bugs or usability issues.


I needed to use a link with onLoad attribute in my head where div is not allowed so this caused me significant pain. My current workaround is to close the original script tag, do what I need to do, then open script tag (to be closed by the original). Hope this might help someone who has absolutely no other choice:

<script dangerouslySetInnerHTML={{ __html: `</script>
   <link rel="preload" href="" as="style" onLoad="this.onload=null;this.rel='stylesheet'" crossOrigin="anonymous"/>


Here's a little less opinionated version of the RawHTML function posted before. It lets you:

  • configure the tag
  • optionally replace newlines to <br />'s
  • pass extra props that RawHTML will pass to the created element
  • supply an empty string (RawHTML></RawHTML>)

Here's the component:

const RawHTML = ({ children, tag = 'div', nl2br = true, }) =>
    React.createElement(tag, {
        dangerouslySetInnerHTML: {
            __html: nl2br
                ? children && children.replace(/\n/g, '<br />')
                : children,
RawHTML.propTypes = {
    children: PropTypes.string,
    nl2br: PropTypes.bool,
    tag: PropTypes.string,


<RawHTML>{'First &middot; Second'}</RawHTML>
<RawHTML tag="h2">{'First &middot; Second'}</RawHTML>
<RawHTML tag="h2" className="test">{'First &middot; Second'}</RawHTML>
<RawHTML>{'first line\nsecond line'}</RawHTML>
<RawHTML nl2br={false}>{'first line\nsecond line'}</RawHTML>


<div>First · Second</div>
<h2>First · Second</h2>
<h2 class="test">First · Second</h2>
<div>first line<br>second line</div>
<div>first line
second line</div>

It will break on:

<RawHTML><h1>First &middot; Second</h1></RawHTML>


dangerouslySetInnerHTML should not be used unless absolutely necessary. According to the docs, "This is mainly for cooperating with DOM string manipulation libraries". When you use it, you're giving up the benefit of React's DOM management.

In your case, it is pretty straightforward to convert to valid JSX syntax; just change class attributes to className. Or, as mentioned in the comments above, you can use the ReactBootstrap library which encapsulates Bootstrap elements into React components.


I used this library called Parser. It worked for what I needed.

import React, { Component } from 'react';    
import Parser from 'html-react-parser';

class MyComponent extends Component {
  render() {


export class ModalBody extends Component{
        var rawMarkup = this.props.content
        return { __html: rawMarkup };
                <div className="modal-body">
                     <span dangerouslySetInnerHTML={this.rawMarkup()} />



I have tried this pure component:

const RawHTML = ({children, className = ""}) => 
<div className={className}
  dangerouslySetInnerHTML={{ __html: children.replace(/\n/g, '<br />')}} />


  • Takes classNameprop (easier to style it)
  • Replaces \n to <br /> (you often want to do that)
  • Place content as children when using the component like:
  • <RawHTML>{myHTML}</RawHTML>

I have placed the component in a Gist at Github: RawHTML: ReactJS pure component to render HTML


I have used this in quick and dirty situations:

// react render method:

render() {
    return (
        { this.props.textOrHtml.indexOf('</') !== -1
            ? (
                <div dangerouslySetInnerHTML={{__html: this.props.textOrHtml.replace(/(<? *script)/gi, 'illegalscript')}} >
            : this.props.textOrHtml



dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack.

It is better/safer to sanitise your raw HTML (using e.g., DOMPurify) before injecting it into the DOM via dangerouslySetInnerHTML.

DOMPurify - a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify works with a secure default, but offers a lot of configurability and hooks.


import React from 'react'
import createDOMPurify from 'dompurify'
import { JSDOM } from 'jsdom'

const window = (new JSDOM('')).window
const DOMPurify = createDOMPurify(window)

const rawHTML = `
<div class="dropdown">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
    <span class="caret"></span>
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>

const YourComponent = () => (
    { <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(rawHTML) }} /> }

export default YourComponent


There are now safer methods to render HTML. I covered this in a previous answer here. You have 4 options, the last uses dangerouslySetInnerHTML.

Methods for rendering HTML

  1. Easiest - Use Unicode, save the file as UTF-8 and set the charset to UTF-8.

    <div>{'First · Second'}</div>

  2. Safer - Use the Unicode number for the entity inside a Javascript string.

    <div>{'First \u00b7 Second'}</div>


    <div>{'First ' + String.fromCharCode(183) + ' Second'}</div>

  3. Or a mixed array with strings and JSX elements.

    <div>{['First ', <span>&middot;</span>, ' Second']}</div>

  4. Last Resort - Insert raw HTML using dangerouslySetInnerHTML.

    <div dangerouslySetInnerHTML={{__html: 'First &middot; Second'}} />

Related Query

More Query from same tag