Author avatar

Gaurav Singhal

How to Use Static HTML with React

Gaurav Singhal

  • Jul 3, 2020
  • 4 Min read
  • 251 Views
  • Jul 3, 2020
  • 4 Min read
  • 251 Views
Web Development
Front End Web Development
Client-side Framework
React

Introduction

There may be an instance where you would want to display HTML inside a React Component. The HTML could be from an external source or a file that you want to display to the user.

By default, React does not permit you to inject HTML in a component, for various reasons including cross-site scripting. However, for some cases like a CMS or WYSIWYG editor, you have to deal with raw HTML. In this guide, you will learn how you can embed raw HTML inside a component.

dangerouslySetInnerHTML Prop

If you try to render an HTML string inside a component directly, React will automatically sanitize it and render it as a plain string.

1
2
3
const myHTML = `<h1>John Doe</h1>`;

const App = () => <div>{myHTML}</div>;
jsx

The above code will not render the string "John Doe" in a heading. Instead, the complete string, including the H1 tags, will be displayed to the user, thanks to React.

To render the string as HTML, you need to use the dangerouslySetInnerHTML prop.

1
2
3
const myHTML = `<h1>John Doe</h1>`;

const App = () => <div dangerouslySetInnerHTML={{ __html: myHTML }} />;
jsx

The dangerouslySetInnerHTML prop was built to present and inject DOM formatted content into the frontend. The use of this prop is considered a bad practice, especially when dealing with user inputs. You should consider any user input as unsafe and sanitize it before injecting it into the frontend.

The dangerouslySetInnerHTML prop must be an object with a key __html and value of an HTML string. Misusing the dangerouslySetInnerHTML prop might open up your app to cross-site scripting attacks. Hence, before using this prop, you need to ensure that the HTML string is sanitized properly and coming from a reliable source. You should avoid passing any user-accepted input into the dangerouslySetInnerHTML prop.

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) attacks allow a malicious user or hacker to inject unsafe HTML code into a website for other end users. This allows the hacker to access personal data like cookies, local storage, etc.

Safer Alternative to dangerouslySetInnerHTML

If XSS is a primary concern, you can use an external library like DOMPurify to sanitize the HTML string before injecting it into the DOM using the dangerouslySetInnerHTML prop.

To install the DOMPurify library, run the following command.

1
npm i dompurify
ssh

You can see the example usage below.

1
2
3
4
5
6
7
import DOMPurify from "dompurify";

const myHTML = `<h1>John Doe</h1>`;

const mySafeHTML = DOMPurify.sanitize(myHTML);

const App = () => <div dangerouslySetInnerHTML={{ __html: mySafeHTML }} />;
jsx

You can also configure DOMPurify to allow only specific tags and attributes.

1
2
3
4
5
6
// ...
const mySafeHTML = DOMPurify.sanitize(myHTML, {
  ALLOWED_TAGS: ["h1", "p", "span"],
  ALLOWED_ATTR: ["style"],
});
// ...
jsx

Conclusion

Security is the primary concern when dealing with HTML content from the user. You cannot trust any input from users, even admin users who are maintaining or writing content for the app. Hence you should always sanitize the HTML content using DOMPurify or any other library before injecting it into the DOM. Keep in mind that sanitizing large HTML strings on the client side might degrade the app performance; fortunately, DOMPurify can also be used on a NodeJS server, and therefore you should consider sanitizing the content in the backend.

2