How can I render HTML from another file in a React component?

JavascriptReactjs

Javascript Problem Overview


Is it possible to render HTML from another file in a React component?

I have tried the following, but it does not work:

var React = require('react');

/* Template html */
var template = require('./template');

module.exports = React.createClass({
    render: function() {
        return(
            <template/>
        );
    }
});

Javascript Solutions


Solution 1 - Javascript

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.

Solution 2 - Javascript

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>'

Solution 3 - Javascript

You can use dangerouslySetInnerHTML to do this:

import React from 'react';
function iframe() {
    return {
        __html: '<iframe src="./Folder/File.html" width="540" height="450"></iframe>'
    }
}


export default function Exercises() {
    return (
        <div>
            <div dangerouslySetInnerHTML={iframe()} />
        </div>)
}

HTML files must be in the public folder

Solution 4 - Javascript

It is common to have components that are only rendering from props. Like this:

class Template extends React.Component{
  render (){
    return <div>this.props.something</div>
  }
}

Then in your upper level component where you have the logic you just import the Template component and pass the needed props. All your logic stays in the higher level component, and the Template only renders. This is a possible way to achieve 'templates' like in Angular.

There is no way to have .jsx file with jsx only and use it in React because jsx is not really html but markup for a virtual DOM, which React manages.

Solution 5 - Javascript

You could do it if template is a react component.

Template.js

var React = require('react');

var Template = React.createClass({
    render: function(){
        return (<div>Mi HTML</div>);
    }
});

module.exports = Template;

MainComponent.js

var React = require('react');
var ReactDOM = require('react-dom');
var injectTapEventPlugin = require("react-tap-event-plugin");
var Template = require('./Template');

//Needed for React Developer Tools
window.React = React;

//Needed for onTouchTap
//Can go away when react 1.0 release
//Check this repo:
//https://github.com/zilverline/react-tap-event-plugin
injectTapEventPlugin();

var MainComponent = React.createClass({
    render: function() {
        return(
            <Template/>
        );
    }
});

// Render the main app react component into the app div.
// For more details see: https://facebook.github.io/react/docs/top-level-api.html#react.render
ReactDOM.render(
  <MainComponent />,
  document.getElementById('app')
 );

And if you are using Material-UI, for compatibility use Material-UI Components, no normal inputs.

Solution 6 - Javascript

i-frame src accepts only http protocols. So, if you are loading any static html from your machine, the browser URL will likely be "file: //home/myComputer/localOfFiles/myHTMLfile.html" and the correct path should be "http://localhost:3000/myHTMLfile.html";.

You don't need to use any extension or anything else, you just move a myHTMLfile.html to your public folder in React code and try this path "http://localhost:3000/myHTMLfile.html";. This solution is borrowed from here (worked for me though its for pdf rendering)-

https://github.com/wojtekmaj/react-pdf/issues/300#issuecomment-846226460

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEmir MarquesView Question on Stackoverflow
Solution 1 - JavascriptDan PrinceView Answer on Stackoverflow
Solution 2 - JavascriptJon SurrellView Answer on Stackoverflow
Solution 3 - JavascriptNelson Javier GarzonView Answer on Stackoverflow
Solution 4 - JavascriptIvanView Answer on Stackoverflow
Solution 5 - JavascriptAllanView Answer on Stackoverflow
Solution 6 - Javascriptnagbaht25View Answer on Stackoverflow