How to Merge React App into existing Website with existing HTML structure

Viewed 1262

We have a <html> file stored on AWS S3. The file contains header and footer information.

This file has it's own build pipeline, we collect some data from a database and generate the HTML and upload to S3.

We would now like to include a bundled React App into this HTML page. I.e. within the body of the page will be the bundled react application.

The React App is built on the latest create-react-app setup and therefore, babel and webpack are pre-configured. The react build creates all the relevant files if the app was hosted without the above setup.

Is there a way to merge the two pages?

**Notes: Specifically looking for a merge as part of the build process. **

  1. We have one project that generates a header html and publishes it onto an S3. We have triggers that might trigger this to regenerate at specific times/after changes etc.

  2. We have a React App that is bundled with babel/webpack in a production build and produces the output HTML/bundle js etc. All minified and hashed, so the file names are bundle.randomhash.js etc.

We need to merge the two outputs. The html file from S3 needs to include the React App within its body/html.

Ideally in a pipeline/build process. So if one changes, the merge is re-compiled/re-run.

2 Answers

To do this you need to host your js, css, and media files from your react build folder in an S3 bucket and add the following to the code.

<html>
    ..... your static html code 


    <div id="the id used to bootstrap your react app (from the index.html file in the public folder)"></div>

    ......
    links to all the files in your JS, CSS And media files from the react build folder

</html>

I would suggest to use hosted images (you can host them on S3 as well) and assets as much as possible so you don't need to add the media file links on by one in the html file.

You may want to look at this link on how to bundle all files into one file when building your react app (I haven't tried this part).

I think you are looking for an automatic way of merging two outputs, one being your existing HTML with header and footer generated from your existing build process and triggered via a database.

The second being your react app which is a well finished final output that comes out of your create-react-app build infrastructure.

In such a case, I would recommend to use this very popular tool called gulp-inject. gulp-inject takes a stream of source files, transforms each file to a string and injects each transformed string into placeholders in the target stream files.

An example is given below:

Let's say your target file is called index.html like this

<!DOCTYPE html>
<html>
<head>
  <title>My index</title>
  <!-- inject:css -->
  <!-- endinject -->
</head>
<body>
 
  <!-- inject:js -->
  <!-- endinject -->
</body>
</html>

Your gulpfile.js script would look like this to achieve a new index.html with new insertions automatically based on this script.

var gulp = require('gulp');
var inject = require('gulp-inject');
 
gulp.task('index', function () {
  var target = gulp.src('./src/index.html');
  // It's not necessary to read the files (will speed up things), we're only after their paths:
  var sources = gulp.src(['./src/**/*.js', './src/**/*.css'], {read: false});
 
  return target.pipe(inject(sources))
    .pipe(gulp.dest('./src'));
});

Your final output of your index.html would look like this after running gulp index:

<!DOCTYPE html>
<html>
<head>
  <title>My index</title>
  <!-- inject:css -->
  <link rel="stylesheet" href="/src/style1.css">
  <link rel="stylesheet" href="/src/style2.css">
  <!-- endinject -->
</head>
<body>
 
  <!-- inject:js -->
  <script src="/src/lib1.js"></script> 
  <script src="/src/lib2.js"></script> 
  <!-- endinject -->
</body>
</html>

The basics of converting an existing HTML file and inserting it with ReactJS code is given below. I think if you apply these principles and use the gulp-inject tool, you can achieve wonders.

https://reactjs.org/docs/add-react-to-a-website.html

Your exact build automation maybe driven by your own tool such as Jenkins or such similar tools where you could chain one event with the other. For example, you could check whenever a new HTML file is automatically generated by your Database Triggering on AWS and once that event is received, you could trigger either the Gulp-Inject script if you already have the React Component(s) ready or trigger the Create-React-App to freshly build the React Component and then apply the Gulp-Inject script to inject your React Component or React Code into the index.html or whatever the name of your html page.

The npm package for gulp-inject can be found here.

https://www.npmjs.com/package/gulp-inject

Hope this helps. Let me know.

If you like the answer, you can accept it.

Related