Automated HTML Files For Isomorphic React Apps

Pranesh Ravi
Pranesh Ravi’s Blog
4 min readSep 2, 2017

--

Recently, I built my first isomorphic React app. During that process, I referred many boilerplates to understand how they generate the final HTML files as I had a hard time generating those. I found a common problem in the way the HTML files were being generated and I came up with a solution for the same which I would like to share with everyone.

The following article assumes that you’re familiar with React, Webpack and Express.

The Problem

Almost every boilerplate used Template strings or a separate React class to generate the HTML files. All the assets were added into it based on the manifest file generated by webpack. The following snippet is from react-redux-universal:

Separate react class returning HTML file

Here, they have a separate React class which renders the HTML. All the assets are passed as a prop and populated into the HTML.

This looks good. But is it scalable? Say, you need to add a favicon. The usual way is to add a <link> tag with the location to the icon. Now, let’s say you need to add different types/sizes of favicon. Will you add all the different types manually? Is it the right solution?

The answer is NO!! It is a painful process, adding everything manually.

When I develop non isomorphic React apps, I use HTML-webpack-plugin to generate my HTML files and favicons-webpack-plugin to generate different types/sizes of favicon from a single image and inject them into my HTML files. It is totally automated and scalable. But we can’t use this plugin for isomorphic apps because the server will need a template to inject dynamic content whereas the plugin returns a HTML file not a template.

The Solution

With a simple hack you can use HTML-webpack-plugin to return a template file instead of a HTML file which can be used for isomorphic apps. On a high level, we pass a template file to the plugin which returns a template file with all necessary assets pre-injected. We then use this template file in the server to inject the dynamic content created by React and return the complete HTML to the clients.

High level workflow

First, install the required modules:

yarn add html-webpack-plugin favicons-webpack-plugin handlebars-loader express-handlebars -D

I’m using Handlebars as the template engine. Feel free to choose the one with which you’re comfortable.

Then, create a Handlebars template file like the following:

Base template for HTML-webpack-plugin

It is very important to escape the template expressions which you think should be parsed in the server. For example, here I need the HTML contents to be populated in the server. So, I need to escape {{{html}}} with a \ in the front. This expression will be ignored during the Handlebars loader’s parse during webpack build.

Escaped expressions will be converted as a normal string which will be used by express-handlebars to parse and inject contents in the server 🙌

Then update your webpack configuration to use the HTML-webpack-plugin.

Webpack configuration to use HTML-webpack-plugin

Here, you need to specify the output file type as .hbs so that it can be used in the server as a Handlebars template. This is very important!

Pro Tip

HTML-webpack-plugin also allows you to minify output files. You can utilize this to save few bytes over the network.

When you run webpack, you will get a template file similar to the following:

Template generated by HTML-webpack-plugin

Now, we have a template file with all the assets and the favicons added leaving the {{{html}}} , which we’ll be using in the server to inject dynamic content.

Now, in the server (I’m using express for this example), register the Handlebars engine and use the obtained index.hbs as the base layout template.

Using the webpack generated template in server

This will take the template built by HTML-webpack-plugin as the base layout, parse and replace the expressions, if any, with contents.

TADA!! Now you have a fully automated and highly scalable way of generating HTML files for your isomorphic React apps.

Advantages

  • Fully automated and scalable
  • No need to generate manifest file
  • Able to take advantage of HTML-webpack-plugin and its powerful add ons
  • Able to take advantage of the template engine
  • Less code in the server

If you have any suggestions or questions, comment below or write to me at talkto@praneshravi.in

I’m also currently writing a detailed blog on building Progressive Web App from scratch. So, stay tuned to my blog.

Happy Hacking! 💻 ❤️

--

--