nx: Environment Variables not available in index.html for webpack 5 builds (React)

Current Behavior

In the NX docs, it states that you can access the environment variables in the index.html file like so: https://nx.dev/latest/react/guides/environment-variables#using-environment-variables-in-indexhtml

For a react app that uses webpack 5, this is not the case. It does not replace the placeholder with the environment variable in the .env file.

Expected Behavior

The environment variables should be injected into the index.html folder at build time.

Steps to Reproduce

  • Create a new NX repo with a react app: npx create-nx-workspace@latest
  • In the react app, add a .env file with a variable in e.g. NX_TEST_VARIABLE='xyz'
  • In the index.html file add the following tag to the body: <p>%NX_TEST_VARIABLE%</p>
  • Run nx serve app - observe that the env variable is populated on the screen
  • Now upgrade from webpack 4 to webpack 5 npx nx g @nrwl/web:webpack5
  • Run nx serve app again - observe that now the env var is not populated and you see: %NX_TEST_VARIABLE% instead

Failure Logs

No visible failure logs

Environment

NX report: Node : 14.17.3 OS : darwin x64 npm : 7.20.0

nx : Not Found @nrwl/angular : Not Found @nrwl/cli : 12.8.0 @nrwl/cypress : 12.8.0 @nrwl/devkit : 12.8.0 @nrwl/eslint-plugin-nx : 12.8.0 @nrwl/express : Not Found @nrwl/jest : 12.8.0 @nrwl/linter : 12.8.0 @nrwl/nest : Not Found @nrwl/next : Not Found @nrwl/node : Not Found @nrwl/nx-cloud : Not Found @nrwl/react : 12.8.0 @nrwl/schematics : Not Found @nrwl/tao : 12.8.0 @nrwl/web : 12.8.0 @nrwl/workspace : 12.8.0 @nrwl/storybook : 12.8.0 @nrwl/gatsby : Not Found typescript : 4.3.5

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (4 by maintainers)

Most upvoted comments

I’m not really sure how to fix the issue. But we created a workaround for our project since we needed some conditional rendering in our index.html (scripts injected if env variable is defined and so on). Maybe it could fit your needs as well.

  1. Create a webpack.config.js in your apps root folder:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = (config, context) => {
  const template = context.buildOptions?.index ?? context.options?.index;

  // Remove the current html plugin added by NX
  let idx = config.plugins.findIndex((plugin) => plugin.constructor.name === 'IndexHtmlWebpackPlugin');
  config.plugins.splice(idx, 1);

  // Push our own version with ejs template syntax enabled
  config.plugins.push(new HtmlWebpackPlugin({ template: path.join(process.cwd(), template) }));

  return config;
};
  1. Configure your build target to use the extended webpack config:
{
  // ...
  "build": {
    "executor": "@nrwl/web:build",
    "outputs": ["{options.outputPath}"],
    "options": {
      // ...
      "index": "apps/admin/src/index.html", // <- important
      "webpackConfig": "apps/admin/webpack.config.js", // <- important
      "generateIndexHtml": false, // <- important
    },
    // ...
  },
}

With this you can use ejs template stuff in your index.html file:

<% if (process.env.NODE_ENV === "production" && process.env.NX_SEGMENT_KEY) { %>
  <script>
    analytics.load(<%= JSON.stringify(process.env.NX_SEGMENT_KEY) %>);
  </script>
<% } %>

Thank you for investigating this @jaysoo!

We decided not to add the same support to Angular for now since we don’t control the executor/builder. However, I am updating the guide to include some workarounds.

Preview: https://nx-dev-git-fork-jaysoo-docs-env-vars-nrwl.vercel.app/guides/environment-variables#using-environment-variables-in-angular-applications PR: https://github.com/nrwl/nx/pull/10045

Since it sounds like an Angular-specific issue, I’m going to close this once the docs are updated. If you want the same support for Angular, please open a new enhancement issue and we can consider adding it.

Hi @neilsoult , thanks for the repro.

The problem right now is that @angular-devkit/build-angular-browser doesn’t provide the same environment variable support that our executors provide. Let me pull in some people working on the Angular side of things to see where we want to do here.