The way I see it is that you have 2 problems to solve here. The first is how to set the innerHTML of an element in React. The other is how to get a specific HTML to render depending on a given variable (e.g the current route, the input of a textfield, etc).
1. Setting the innerHTML of an element
You can do this with the dangerouslySetInnerHTML prop. As the name suggests it sets the innerHTML of the said element to whatever you specify... and yes, the "dangerously" is accurate as it's intended to make you think twice before using this feature.
The Official Documentation reads as follows:
Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the leading causes of web vulnerabilities on the internet.
Check out this Demo or the snippet below.
var Demo = React.createClass({
getInitialState: function() {
return {showExternalHTML: false};
},
render: function() {
return (
<div>
<button onClick={this.toggleExternalHTML}>Toggle Html</button>
{this.state.showExternalHTML ? <div>
<div dangerouslySetInnerHTML={this.createMarkup()} ></div>
</div> : null}
</div>
);
},
toggleExternalHTML: function() {
this.setState({showExternalHTML: !this.state.showExternalHTML});
},
createMarkup: function() {
return {__html: '<div class="ext">Hello!</div>'};
}
});
ReactDOM.render(
<Demo />,
document.getElementById('container')
);
.ext {
margin-top: 20px;
width: 100%;
height: 100px;
background: green;
color: white;
font-size: 40px;
text-align: center;
line-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
2. Fetching the HTML from an external source
Note that the above example does not actually get the HTML from an external file, but is entered directly as a string.
One simple way to do dynamically fetch a choose a specific file would be to let your backend (e.g php) read the file from a local folder, parse the text, and send it back through an AJAX request.
Example
//Your React component
fetchExternalHTML: function(fileName) {
Ajax.getJSON('/myAPI/getExternalHTML/' + fileName).then(
response => {
this.setState({
extHTML: response
});
}, err => {
//handle your error here
}
);
}
Answer from Chris on Stack OverflowThe way I see it is that you have 2 problems to solve here. The first is how to set the innerHTML of an element in React. The other is how to get a specific HTML to render depending on a given variable (e.g the current route, the input of a textfield, etc).
1. Setting the innerHTML of an element
You can do this with the dangerouslySetInnerHTML prop. As the name suggests it sets the innerHTML of the said element to whatever you specify... and yes, the "dangerously" is accurate as it's intended to make you think twice before using this feature.
The Official Documentation reads as follows:
Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the leading causes of web vulnerabilities on the internet.
Check out this Demo or the snippet below.
var Demo = React.createClass({
getInitialState: function() {
return {showExternalHTML: false};
},
render: function() {
return (
<div>
<button onClick={this.toggleExternalHTML}>Toggle Html</button>
{this.state.showExternalHTML ? <div>
<div dangerouslySetInnerHTML={this.createMarkup()} ></div>
</div> : null}
</div>
);
},
toggleExternalHTML: function() {
this.setState({showExternalHTML: !this.state.showExternalHTML});
},
createMarkup: function() {
return {__html: '<div class="ext">Hello!</div>'};
}
});
ReactDOM.render(
<Demo />,
document.getElementById('container')
);
.ext {
margin-top: 20px;
width: 100%;
height: 100px;
background: green;
color: white;
font-size: 40px;
text-align: center;
line-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
2. Fetching the HTML from an external source
Note that the above example does not actually get the HTML from an external file, but is entered directly as a string.
One simple way to do dynamically fetch a choose a specific file would be to let your backend (e.g php) read the file from a local folder, parse the text, and send it back through an AJAX request.
Example
//Your React component
fetchExternalHTML: function(fileName) {
Ajax.getJSON('/myAPI/getExternalHTML/' + fileName).then(
response => {
this.setState({
extHTML: response
});
}, err => {
//handle your error here
}
);
}
While Chris's answer was good, some more digging was required to make it work. Here are the steps that you need to take:
Add html loader to your project:
npm i -D html-loader
Add the following rule to your webpack.config file:
{
test: /\.(html)$/,
use: {
loader: 'html-loader',
options: {
attrs: [':data-src']
}
}
}
Now you can import your html file as follow:
import React, { Component } from 'react';
import Page from './test.html';
var htmlDoc = {__html: Page};
export default class Doc extends Component {
constructor(props){
super(props);
}
render(){
return (<div dangerouslySetInnerHTML={htmlDoc} />)
}}
reactjs - How to load external HTML file in react components? - Stack Overflow
How can I render HTML from another file in a React component?
How to input external react app into main html file?
reactjs - how to import HTML file into React component and use it as a component? - Stack Overflow
Videos
If your template.html file is just HTML and not a React component, then you can't require it in the same way you would do with a JS file.
However, if you are using Browserify — there is a transform called stringify which will allow you to require non-js files as strings. Once you have added the transform, you will be able to require HTML files and they will export as though they were just strings.
Once you have required the HTML file, you'll have to inject the HTML string into your component, using the dangerouslySetInnerHTML prop.
var __html = require('./template.html');
var template = { __html: __html };
React.module.exports = React.createClass({
render: function() {
return(
<div dangerouslySetInnerHTML={template} />
);
}
});
This goes against a lot of what React is about though. It would be more natural to create your templates as React components with JSX, rather than as regular HTML files.
The JSX syntax makes it trivially easy to express structured data, like HTML, especially when you use stateless function components.
If your template.html file looked something like this
<div class='foo'>
<h1>Hello</h1>
<p>Some paragraph text</p>
<button>Click</button>
</div>
Then you could convert it instead to a JSX file that looked like this.
module.exports = function(props) {
return (
<div className='foo'>
<h1>Hello</h1>
<p>Some paragraph text</p>
<button>Click</button>
</div>
);
};
Then you can require and use it without needing stringify.
var Template = require('./template');
module.exports = React.createClass({
render: function() {
var bar = 'baz';
return(
<Template foo={bar}/>
);
}
});
It maintains all of the structure of the original file, but leverages the flexibility of React's props model and allows for compile time syntax checking, unlike a regular HTML file.
You can use the dangerouslySetInnerHTML property to inject arbitrary HTML:
// Assume from another require()'ed module:
var html = '<h1>Hello, world!</h1>'
var MyComponent = React.createClass({
render: function() {
return React.createElement("h1", {dangerouslySetInnerHTML: {__html: html}})
}
})
ReactDOM.render(React.createElement(MyComponent), document.getElementById('app'))
<script src="https://fb.me/react-0.14.3.min.js"></script>
<script src="https://fb.me/react-dom-0.14.3.min.js"></script>
<div id="app"></div>
You could even componentize this template behavior (untested):
class TemplateComponent extends React.Component {
constructor(props) {
super(props)
this.html = require(props.template)
}
render() {
return <div dangerouslySetInnerHTML={{__html: this.html}}/>
}
}
TemplateComponent.propTypes = {
template: React.PropTypes.string.isRequired
}
// use like
<TemplateComponent template='./template.html'/>
And with this, template.html (in the same directory) looks something like (again, untested):
// ./template.html
module.exports = '<h1>Hello, world!</h1>'
» npm install html-to-react-components
You can import or require the html file and use it in the src attribute,
var perf =require('./template.html');
class Index extends React.Component {
render(){
return (
<iframe src={perf }></iframe> /* like this */
);
}
}
export default Index;
Spent 2 hours on this.
Two ways to do the same below:
- Method1 -
iframe(part of page) goes to that html file (chap3.htm) - Method2 -
fetchthe contents ofchap3.htmand set to state, state is added withdangerouslySetInnerHTML
NOTE
- Html file is in
publicdirectory (myapp\public\chap3.htm). - May work from current directory too, but does not look like as a usual way to load static resource/html from current directory.
Method 1
import React from'react';
import'./App.css';
function App() {
return(
<div className="App">
<iframe src="chap3.htm"></iframe>
</div>
);
}
export default App;
Method 2
import React, { useEffect, useState }from'react';
import'./App.css';
function App() {
let[htmlFileString, setHtmlFileString] = useState();
async function fetchHtml() {
setHtmlFileString(await (await fetch(`chap3.htm`)).text());
}
useEffect(() => {
fetchHtml();
}, []);
return(
<div className="App">
<div dangerouslySetInnerHTML={{ __html: htmlFileString }}></div>
</div>
);
}
export default App;
You can use dangerouslySetInnerHTML to insert html in react component. This will render the whole html inside the div tag.
const content = `<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<style type="text/css">
@import url('https://themes.googleusercontent.com/fonts/css?kit=fpjTOVmNbO4Lz34iLyptLUXza5VhXqVC6o75Eld_V98');.lst-kix_list_1-3>li:before{content:"\0025cf "}.lst-kix_l.......
</style>
</head>
<body class="c16">
<div>Test</div>
</body>
</html>`
class TermsAndConditionsPage extends React.Component {
render() {
return <div dangerouslySetInnerHTML={{ __html: content }}/>
}
}
From the docs:
dangerouslySetInnerHTMLis 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 across-site scripting > (XSS) attack. So, you can set HTML directly from React, but you have to type outdangerouslySetInnerHTMLand pass an object with a __html key, to remind yourself that it’s dangerous.
If looking for the easiest, quickest method, dangerouslySetInnerHTML will do the trick as the other answer mentions.
If you don't mind some manual work, you could use online tools like https://premailer.io/
- copy over all CSS declarations in the
imported sheet intoheadarea withinstyletag - copy the entire
htmldocument into the input area at https://premailer.io/ - hit convert
You'll then end up with the complete html document with every CSS style inlined, which you could use as JSX.