Displaying HTML Strings in React using dangerouslySetInnerHTML

Daniel Pericich
5 min readJan 29, 2021

I was working on a company’s coding challenge recently and came across something that seemed at first very odd. The challenge was replicating a front end comparison tool from a png mockup and a JSON file mocking an API call.

After flexing my flexbox powers, I came across a section of the UI that I was not familiar with. It was an unordered list of features for the different plans shown in the tool. Consulting the JSON file, I found the information I needed to create this list. The value for the object was a string containing HTML <ul> and <li> elements.

I first thought about simply placing this string between divs, but realized this would just return the HMTL as text. While I couldn’t figure out what a React solution would be, this issue reminded me of targeting and inserting text in HTML elements with innerHTML. From this I was able to come across React’s equivalent, dangerouslySetInnerHTML.

Before we dive into this attribute, I want to take some time to review how properties and attributes are used in React. React uses a virtual DOM for performance and browser compatibility and even has modified properties and attributes. React uses camelCase for properties and attributes names and has even changed some attribute names and the way they are utilized.

If you’ve worked with React before, you have noticed that event handlers show up as “onClick” instead of “click”, but React goes a step further with others such as changing innerHTML to dangerouslySetInnerHTML. Always consult the docs if you have questions (link in resources).

You can use the JavaScript object property innerHMTL for a number of things. While you can insert strings from an API call into display elements, it is also useful for alerting users to errors in a form. I put together a quick demo below in which I create a simple single input form that will accept users’ input and display an error if the user does not enter a name:

Figure 1 : Vanilla JS error-handling

Here we have the form set up, including an empty div with a class of error-message between the label and input. While there are ways to approach error messages in which you toggle class names to make the error message appear i.e. “display: none” to “display: block”, here we are going to simply insert text in the error-message p element if the form validation is not successful. In this case it is not, so we set the innerHTML property of our error object to the error message text which is then displayed on our screen. Now our user knows they need to correct information before moving forward, great!

React works differently in its approach to setting HTML from code. One concern with setting HTML from code is the risk of XSS or cross-site scripting. This is a malicious injection type attack that is often exploited in situations that a user inputs information that is then shown as output in the app. Because of this, React named their version of innerHTML as dangerouslySetInnerHTML. This name is a reminder to developers that this method of coding can put users at risk.

While there is risk involved, it is not dangerous if you take proper precautions such as using a library to sanitize user inputs before your code uses these inputs and using eslint rules to alert dirty code issues during development. There is a link in the resources on how to properly sanitize code to make dangerouslySetInnerHTML safe for use.

Along with the name change, React uses a different mechanism for setting the value of the element. Instead of simply setting the elements value to a string like we did in the Vanilla JavaScript example above, you have to pass the attribute an object. React requires a format of dangerouslySetInnerHTML = {__html : “your code” } for using this attribute. There’s nothing special about this, other than the extra effort reminds you that this code can be dangerous.

I put together a quick example of how to use dangerouslySetInnerHTML based off the situation I ran into during my homework. Below I have a picture of the mock API json file:

Figure 2: Mock API JSON recipe response

You can see that we have a number of fields for each recipe including the dish title, how many people it serves, the cook time and a HTML string of the ingredients list. Our React component is going to be very bare bones and only focus on the title and ingredients:

Figure 3: Recipe React Element

Here we receive props of title and ingredients into our component and want to display them in our card. The title is simply passed in as JSX for the title div, but we have to use something else for the string HTML containing our ingredients. Here we turn to dangerouslySetInnerHTML to insert our text into the div. Using the dangerouslySetInnerHTML attribute, we pass it an object with a key of __html and our ingredients prop as the value to insert and are returned our card!

While there are other ways to do error messages or show text inside a div, the dangerouslySetInnerHTML attribute is very handy when you want a quick way to insert string HTML into an element. Though it does introduce the possibilities of XSS, these can be lessened or removed by properly cleaning user input. I hope you enjoyed this article. Leave a comment if you have used or plan to use dangerouslySetInnerHTML in your projects!

Resources

https://reactjs.org/docs/dom-elements.html

https://owasp.org/www-community/attacks/xss/

https://dev.to/jam3/how-to-prevent-xss-attacks-when-using-dangerouslysetinnerhtml-in-react-1464

--

--

Daniel Pericich

Former Big Beer Engineer turned Full Stack Software Engineer