How To Conditionally Change index.html in React
Tags: frontend, javascript, programming, react
Published: 2024-01-19 21:13:36

When developing a [React](https://reactjs.org/) app, you might need to include or change scripts or HTML tags based on the [environment you are building for](https://writech.run/blog/how-to-correctly-build-a-multi-environment-react-app-6ba4878e98ba). This is especially true when dealing with [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization) or tracking tools, such as [Google Analytics](https://analytics.google.com/analytics/web/) or [HotJar](https://www.hotjar.com/).

What you may not know is that React applications initialized with [Create React App](https://github.com/facebook/create-react-app) offer you the possibility to do so. Although it's very difficult to find documentation for it online, it is actually a cool feature. In fact, with only a handful of lines of code, you can make your `index.html` file content depend on environment variables.

Let's learn more about this little-known feature and see how to use it.

## Conditional Code With HtmlWebpackPlugin

[`HtmlWebpackPlugin`](https://webpack.js.org/plugins/html-webpack-plugin/) comes with Create React App, and it is employed for bundling. Specifically, it uses `public/index.html` as a template and injects a `<script>` with the path provided by [`webpack`](https://webpack.js.org/) to produce the final HTML page.

Also, `HtmlWebpackPlugin` offers developers the ability to deal with conditional code with the following syntax:

```html
<% if (condition) { %>
    // code inserted in the final HTML file only if
    // condition is true
<% } %>
```

You can also use the `else` and/or `if else` branch as follows:

```html
<% if (condition1) { %>
    // code inserted in the final HTML file only if
    // condition1 is true
<% } else if (contition2) { %>
    // code inserted in the final HTML file only if
    // condition1 is true
<% } else { %>
    // code inserted in the final HTML file only if
    // both condition1 and contition2 are false
<% } %>
```

Plus, while debugging, you may also need to print the value of a variable or condition. You can do that with this syntax:

```html
<%= variable %>
```

At the end of an [`npm build`](https://docs.npmjs.com/cli/v6/commands/npm-build) or [`npm start`](https://docs.npmjs.com/cli/v7/commands/npm-start) process, you will find its value printed in the HTML file generated.

## Conditional Code in Action

Let's say you wanted only your production React app to be crawled by Google and Google Analytics to be present only in production. You might think about writing two custom build scripts, but this is not required.

In fact, you can easily achieve both of these results. You only have to conditionally change the code of your `public/index.html` file based on the current environment, as follows:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    
    <!-- GOAL 1 -->
    <% if (process.env.NODE_ENV !== 'production') { %>
        <!-- avoid being crawled -->
        <meta name="robots" content="noindex" />
    <% } %>
    
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    
    <!-- GOAL 2 -->
    <% if (process.env.NODE_ENV === 'production') { %>
        <!-- Google Analytics -->
        <script async src="https://www.googletagmanager.com/gtag/js?id=<YOUR_ID>"></script>
    <% } %>
    
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.
      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.
      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.
      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>
```

What happens is that the two sections written with the special syntax presented above will be included in the final HTML file only when `process.env.NODE_ENV` has the desired value. This environment variable is part of Create React App, as stated in the official documentation.

> _"\[…\] a built-in environment variable called `NODE_ENV`. You can read it from `process.env.NODE_ENV`. When you run `npm start`, it is always equal to `'development'`, when you run `npm test` it is always equal to `'test'`, and when you run `npm run build` to make a production bundle, it is always equal to `'production'`. You cannot override `NODE_ENV` manually."_ — [Create React App](https://create-react-app.dev/docs/adding-custom-environment-variables/)

Et voilà! Your `index.html` content now depends on environment variables.

## Conclusion

Today, we looked at how to make the `index.html` file change based on environment variables. Achieving this goal is easy and involves only a few lines of code. In particular, this is possible thanks to `HtmlWebPackPlugin`, which comes with Create React App by default. This useful, yet not widely known, React feature can save your day by allowing you to avoid writing custom scripts for your environment-targeted builds.

Thanks for reading! I hope that you found this article helpful.
  
***
_The post "[How To Conditionally Change index.html in React](https://writech.run/blog/how-to-conditionally-change-index-html-in-react-de090b51fed3/)" appeared first on [Writech](https://writech.run)._