React is designed to protect against Cross-Site Scripting (XSS) attacks by automatically escaping HTML content. However, there are cases where you need to render raw HTML, such as when working with rich text from a CMS or third-party API. React provides dangerouslySetInnerHTML
for this purpose—but as the name suggests, it must be used with caution.
In this article, we’ll explore best practices for using dangerouslySetInnerHTML
safely in React applications.
What is dangerouslySetInnerHTML
?
dangerouslySetInnerHTML
is a React prop that allows you to inject raw HTML into a component. It bypasses React’s default escaping mechanism, making it potentially dangerous if misused.
Basic Usage:
function MyComponent({ htmlContent }) {
return <div dangerouslySetInnerHTML={{ __html: htmlContent }} />;
}
Risks of Using dangerouslySetInnerHTML
Since this prop directly injects HTML, it can expose your application to:
- XSS Attacks: Malicious scripts can execute if the HTML contains untrusted content.
- Data Leakage: Injected scripts can steal sensitive user data.
- Broken UI: Invalid or poorly formatted HTML can break your layout.
Best Practices for Safe Usage
1. Sanitize HTML Before Rendering
Always sanitize HTML content to remove dangerous scripts, event handlers, and unwanted tags. Use libraries like:
- DOMPurify (Recommended)
- sanitize-html
Example with DOMPurify:
import DOMPurify from 'dompurify';
function SafeHTMLRenderer({ html }) {
const cleanHTML = DOMPurify.sanitize(html);
return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
}
2. Use a Trusted Source
Only use dangerouslySetInnerHTML
with content from trusted sources (e.g., your backend with proper sanitization). Never render user-generated content without validation.
3. Limit Scope with Custom Elements
Instead of rendering large chunks of HTML, isolate dynamic content in specific components:
function TrustedContent({ content }) {
return <div className="trusted-content" dangerouslySetInnerHTML={{ __html: content }} />;
}
4. Avoid Inline Event Handlers
Even if sanitized, avoid allowing onclick
, onload
, or other inline JavaScript handlers.
5. Implement CSP (Content Security Policy)
A strong CSP can mitigate risks by restricting script execution:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
6. Use TypeScript for Additional Safety
Enforce type checks to ensure only valid HTML strings are passed:
interface SafeHTMLProps {
html: string;
}
const SafeHTML: React.FC<SafeHTMLProps> = ({ html }) => {
const clean = DOMPurify.sanitize(html);
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
};
When to Avoid dangerouslySetInnerHTML
- User-generated content (comments, forms) unless strictly sanitized.
- Dynamic script injection – use React components instead.
- Unverified third-party data – prefer APIs that return structured data.
Conclusion
While dangerouslySetInnerHTML
is a powerful tool, it should be used sparingly and with extreme caution. Always sanitize content, trust your sources, and enforce security policies like CSP. By following these best practices, you can minimize risks while leveraging dynamic HTML rendering in React.
Stay safe and happy coding! 🚀
Top comments (0)