Using environment variables in Angular applications
By default, Angular only provides the NODE_ENV
variable when building the application. You may use process.env.NODE_ENV
anywhere in your TS/JS source, and the build will inline this value in the output chunks.
Other variables, such as those prefixed by NX_
will not work in Angular. To add support for other environment variables, do the following.
First, install @types/node
so we can use process.env
in our code.
npm install --save-dev @types/node
# Or with yarn
yarn add --dev @types/node
Next, update the build
and serve
targets (in project.json
or angular.json
file), to the following.
1{
2 "build": {
3 // NOTE: change the executor to one that supports custom webpack config.
4 "executor": "@nrwl/angular:webpack-browser",
5 // snip
6 "options": {
7 // NOTE: This file needs to be created.
8 "customWebpackConfig": {
9 "path": "apps/myapp/webpack.config.js"
10 }
11 // snip
12 }
13 },
14 "serve": {
15 // NOTE: use dev-server that supports custom webpack config.
16 "executor": "@nrwl/angular:webpack-server"
17 // snip
18 }
19}
20
Then, we can use DefinePlugin
in our custom webpack.
1// apps/myapp/webpack.config.js
2const webpack = require('webpack');
3
4function getClientEnvironment(configuration) {
5 // Grab NODE_ENV and NX_* environment variables and prepare them to be
6 // injected into the application via DefinePlugin in webpack configuration.
7 const NX_APP = /^NX_/i;
8
9 const raw = Object.keys(process.env)
10 .filter((key) => NX_APP.test(key))
11 .reduce(
12 (env, key) => {
13 env[key] = process.env[key];
14 return env;
15 },
16 {
17 NODE_ENV: process.env.NODE_ENV || configuration,
18 }
19 );
20
21 // Stringify all values so we can feed into webpack DefinePlugin
22 return {
23 'process.env': Object.keys(raw).reduce((env, key) => {
24 env[key] = JSON.stringify(raw[key]);
25 return env;
26 }, {}),
27 };
28}
29
30module.exports = (config, options, context) => {
31 config.plugins.push(
32 new webpack.DefinePlugin(getClientEnvironment(context.configuration))
33 );
34 return config;
35};
36
Now, when we define variables in our .env
file, such as...
# apps/myapp/.env
NX_API_URL=http://localhost:3333
Finally, We can use environment variables in our code. For example,
1// apps/myapp/src/main.ts
2import { enableProdMode } from '@angular/core';
3import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4import { AppModule } from './app/app.module';
5
6if (process.env['NODE_ENV'] === 'production') {
7 enableProdMode();
8}
9
10// This is defined in our .env file.
11console.log('>>> NX_API_URL', process.env['NX_API_URL']);
12
13platformBrowserDynamic()
14 .bootstrapModule(AppModule)
15 .catch((err) => console.error(err));
16
You should also update tsconfig.apps.json
and tsconfig.spec.json
files to include node types.
1{
2 "extends": "./tsconfig.json",
3 "compilerOptions": {
4 // snip
5 "types": ["node"]
6 }
7 // snip
8}
9
Using environment variables in index.html
While you cannot use variable in index.html
, one workaround for this is to create different index.*.html
files, such as index.prod.html
, then swap it in different environments.
For example in project.json
(or angular.json
),
1{
2 "build": {
3 "executor": "@angular-devkit/build-angular:browser",
4 // snip
5 "configurations": {
6 "production": {
7 // snip
8 "fileReplacements": [
9 {
10 "replace": "apps/myapp/src/environments/environment.ts",
11 "with": "apps/myapp/src/environments/environment.prod.ts"
12 },
13 {
14 "replace": "apps/myapp/src/index.html",
15 "with": "apps/myapp/src/index.prod.html"
16 }
17 ]
18 }
19 }
20 }
21}
22
You can also customize your webpack configuration, similar to using DefinePlugin
above. This approach will require post-processing the index.html
file, and is out of scope for this guide.