How to safely render html in react?
Sanitize the html using the sanitize-html module, and render the sanitized string using dangerouslySetInnerHTML.
You can create a simple wrapper component:
const defaultOptions = {
allowedTags: [ 'b', 'i', 'em', 'strong', 'a' ],
allowedAttributes: {
'a': [ 'href' ]
},
allowedIframeHostnames: ['www.youtube.com']
};
const sanitize = (dirty, options) => ({
__html: sanitizeHtml(
dirty,
options: { ...defaultOptions, ...options }
)
});
const SanitizeHTML = ({ html, options }) => (
<div dangerouslySetInnerHTML={sanitize(html, options)} />
);
Usage:
<SanitizeHTML html="<img src=x onerror=alert('img') />" />
You can also use react-sanitized-html's SanitizedHTML component, which is a react wrapper around sanitize-html
:
<SanitizedHTML
allowedAttributes={{ 'a': ['href'] }}
allowedTags={['a']}
html={ `<a href="http://bing.com/">Bing</a>` }
/>
Rendering raw html with reactjs
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.
How to render HTML string as real HTML?
Check if the text you're trying to append to the node is not escaped like this:
var prop = {
match: {
description: '<h1>Hi there!</h1>'
}
};
Instead of this:
var prop = {
match: {
description: '<h1>Hi there!</h1>'
}
};
if is escaped you should convert it from your server-side.
The node is text because is escaped
The node is a dom node because isn't escaped
How to render HTML from database in react?
You need to set the response.data
to a component state
using useEffect
hook and then render the HTML string using dangerouslySetInnerHTML property.
Try like below.
import React, { useState, useEffect } from "react";
import axios from "axios";
// import {renderWebpage} from "../actions/webpage"
type HTMLData = {
content: { "mycustom-html": string };
};
export const Page: React.FC = () => {
const [htmlData, setHtmlData] = useState<HTMLData>({
content: { "mycustom-html": "<p>demo</p>" }
});
const renderWebpage = () => {
axios
.get("http://localhost:8080/61ea7fd2268f37443ca4d59a")
.then((response) => {
console.log("response", response);
console.log(response.data, "data");
setHtmlData(response.data);
});
};
useEffect(() => {
renderWebpage();
}, []);
return (
<div
dangerouslySetInnerHTML={{
__html: htmlData?.content?.["mycustom-html"]
}}
/>
);
};
Any way to render HTML in react-markdown
The ReactMarkdown
component is for rendering mark down, not HTML mark up . Given HTML input it just escapes it, and that's why you see it as "source", not formatted text.
If you need to use it with HTML you need to apply a plugin, such as rehypeRaw :
import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";
//...
export default function ThePage() {
const markdown = {
description: "<p>Hello from the other </p>\n<p><strong>side</strong></p>"
}
return (
<>
<ReactMarkdown children={markdown.description} rehypePlugins={[rehypeRaw]} />
</>
);
}
Rendering html response from API in React
Async functions always return a Promise
! Make sure you resolve it to get the data.
Refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
Since, the data is fetched from the backend, it may take some time. You can use useEffect
to make the request and set the value you get from the server using useState
.
function MyComponent() {
const [html, setHTML] = useState({__html: ""});
useEffect(() => {
async function createMarkup() {
let response;
response = await fetch(`http://localhost:8000/backed_api/html_response/?user_email=chriss%40comtura.ai`)
const backendHtmlString = await response.text()
console.log(backendHtmlString)
return {__html: backendHtmlString};
}
createMarkup().then(result => setHTML(result));
}, []);
return <div dangerouslySetInnerHTML={html} />;
}
Also, check out this scenario. It could be another case similar to yours.
How to render specific HTML tags from a text in React?
I fixed this by using the dompurify library and created a reusable component in React.
html-tag-renderer.js
import React from 'react';
import DOMPurify from 'dompurify';
import PropTypes from 'prop-types';
const HTMLTagRenderer = ({ string, allowedTags }) => {
const cleanHTML = DOMPurify.sanitize(string, { ALLOWED_TAGS: allowedTags });
return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
};
HTMLTagRenderer.propTypes = {
string: PropTypes.string.isRequired,
allowedTags: PropTypes.array.isRequired,
};
export default HTMLTagRenderer;
can be used like:
<HTMLTagRenderer allowedTags={['b', 'em', 'strong', 'i']} string="This is a text with a <b>bold</b> tag and a <strong>strong</strong> tag. It also includes <i>italic</i> and <em>em</em> tags." />
Related Topics
Flipping/Inverting/Mirroring Text Using CSS Only
Show My Location on Google Maps API V3
Extract Content of Div from Google Translate with Vba
Force Ie Contenteditable Element to Create Line Breaks on Enter Key, Without Breaking Undo
Negative Margins Vs Relative Positioning
Why Is My Element Not Sticking to The Left When Using Position Sticky in CSS
HTML List Isn't Vertically Aligned When Using Floating Images
Images Not Displaying in Github Pages
How to Work with Ellipsis in Bootstrap Responsive Table
How to Set A:Link Height/Width with CSS
Webpage Starts Zoomed in on Mobile Devices
Preventing Fixed Footer from Overlapping Content
HTML5 Input for Money/Currency
Why Don't Svg Images Scale Using The CSS "Width" Property
Align Flex Items with Different Heights in The Same Container