It’s common for developers to have multiple application versions that target different environments i.e. development and production. It’s common that each environment will have some unique environment variables i.e. API Endpoint, app version etc. Angular provides environment configurations to declare variables unique for each environment.

Ideally, you want to automatically apply a flag, let’s say --prod, and the angular compiler replaces the API endpoint variable with the production API endpoint for you. What you don’t want is to manually change the endpoint before building your app. This increases the chance you will make a mistake that might break your app or worse.

Dealing with only 2 Environments

By default angular supports two environments – production and environment. The environment files for the two environments can be located under the environment directory, inside the src directory at the root of your workspace or project folder. You can learn more about angular workspaces here. Inside, there are two files – environment.ts and environment.prod.ts. As you might have guessed, the second file is the production file while the first one is the dev or default environment. Angular CLI compiler, will automatically replace the first file with the second file each time you build with the --prod flag.

ng build --prod

If you open the file, the content of the first one will have production set to false while the second one will have production set to true.

// environment.ts environment variables
export const environment = {
  production: false
};

//environment.prod.ts environment variables
export const environment = {
  production: true
};

All variables which vary based on the environment, should be placed inside these two files appropriately. Check the examples given below for the API Endpoint.

// environment.ts environment variables
export const environment = {
  production: false,
  APIEndpoint: 'https://dev.endpoint.com'
};

// environment.prod.ts environment variables
export const environment = {
  production: true,
  APIEndpoint: 'https://prod.endpoint.com'
};

To access the variables, import the environment constant, and then use it as follows:

import { environment } from './../environments/environment';

Usage

const APIEndpoint = environment.APIEndpoint;

After that, every time you build your application without the --prod flag, then it will use the dev(default) API endpoint while when you use the --prod flag, it will use the production API Endpoint.

Dealing with 3 or More Environment

It’s also common to have more than two environments for your app. You could have, let’s say a staging and beta environments on top of production and dev environment. Angular provides a way to add the extra environments you need manually.

In our case, we need two extra environments – staging and beta, on top of the default two. We start by adding two more environment files next to our two already in existent. Start by creating two new files – environment.staging.ts and environment.beta.ts and then copy the content of the environment.prod.ts to the two files. Next, change the variables to the appropriate values as per your environment.

// environment.staging.ts environment variables
export const environment = {
  production: true
  APIEndpoint: "https://staging.endpoint.com"
};

// environment.beta.ts environment variables
export const environment = {
  production: true,
  APIEndpoint: "https://beta.endpoint.com"
};

Next, we need to make configuration changes to our angular.json – at the root of our workspace. This will enable Angular CLI to recognize our two new environments and use the new environment files we created in the previous step.

First, open angular.json and navigate to the configurations key (Key map: projects -> yourappname -> architect -> build -> configurations). By default, there will be only one key – production, with the following setting:

"configurations": {
   "production": {
       "fileReplacements": [
           {
              "replace": "src/environments/environment.ts",
               "with": "src/environments/environment.prod.ts"
           }
        ],
        "optimization": true,
        "outputHashing": "all",
        "sourceMap": false,
        "extractCss": true,
        "namedChunks": false,
        "aot": true,
        "extractLicenses": true,
        "vendorChunk": false,
        "buildOptimizer": true,
        "serviceWorker": true
   }
}

Duplicate the production key and its content, rename the key from production to staging, then on the fileReplacements key of the staging configuration key, replace:

"with":"src/environments/environment.prod.ts"

with

"with":"src/environments/environment.staging.ts"

Your new configuration for staging environment should look like this:

"configurations": {
   "production": {
        // ...
    },
    "staging": {
    "fileReplacements": [
     {
         "replace": "src/environments/environment.ts",
         "with": "src/environments/environment.staging.ts"
     }],
     "optimization": true,
     "outputHashing": "all",
     "sourceMap": true,
     "extractCss": false,
     "namedChunks": false,
     "aot": false,
     "extractLicenses": true,
     "vendorChunk": false,
     "buildOptimizer": true,
     "serviceWorker": true
   }
}

Repeat the above steps for beta and any extra environments you wish to add.


"beta": {
   "fileReplacements": [
      {
         "replace": "src/environments/environment.ts",
         "with": "src/environments/environment.beta.ts"
      }
   ],
   "optimization": true,
   "outputHashing": "all",
   "sourceMap": false,
   "extractCss": true,
   "namedChunks": false,
   "aot": true,
   "extractLicenses": true,
   "vendorChunk": false,
   "buildOptimizer": true,
   "serviceWorker": true
}

NB: You will need to modify the above settings to closely reflect what you expect on your environment.   For instance, you might want to turn off ServiceWorker on the staging server and leave it on in beta. This will ensure service worker has not cached the app and its resources on the browser when refreshing.

Building your App

Finally, to build your application with the new custom environment, use the –configurations=environment-name flag, as show below:

//for staging environment
ng build --configuration=staging

//for beta environment
ng build --configuration=beta

And for the Angular default environment, there isn’t any changes at all to their build commands.

//for production environment
ng build --prod

//for dev environment
ng build

And that’s it, you can now configure your Angular app with as many environments as you wish.