← Back to Articles         
Manage Environment-specific Configuration

Manage Environment-specific Configuration

Published on 01 Oct 2026     7 min read Angular
Environment & Configuration

How do you manage environment-specific configuration in Angular?

1. What is environment-specific configuration?

Environment-specific configuration means keeping configuration values different depending on where the Angular application is running.

For example:

Environment API URL
Development https://localhost:7001/api
UAT https://uat-api.jntech.in/api
Production https://api.jntech.in/api

Instead of hard-coding the API URL inside Angular services, we keep these values in environment files and let the Angular build configuration select the appropriate file.

A common structure is:

src/
└── environments/
    ├── environment.ts
    ├── environment.uat.ts
    └── environment.production.ts

2. Full Simple Sample Program

Suppose Angular communicates with an ASP.NET Core Web API.

Project structure

src/
│
├── app/
│   ├── models/
│   │   └── product.ts
│   │
│   ├── services/
│   │   └── product.ts
│   │
│   ├── app.ts
│   ├── app.html
│   └── app.config.ts
│
├── environments/
│   ├── environment.ts
│   ├── environment.uat.ts
│   └── environment.production.ts
│
└── main.ts

environment.ts — Development

export const environment = {
  production: false,
  apiUrl: 'https://localhost:7001/api'
};

environment.uat.ts — UAT

export const environment = {
  production: false,
  apiUrl: 'https://uat-api.jntech.in/api'
};

environment.production.ts — Production

export const environment = {
  production: true,
  apiUrl: 'https://api.jntech.in/api'
};

product.ts

export interface Product {
  id: number;
  name: string;
  price: number;
}

services/product.ts

import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

import { Product } from '../models/product';
import { environment } from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private http = inject(HttpClient);

  private apiUrl = `${environment.apiUrl}/products`;

  getProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(this.apiUrl);
  }
}

Notice something important:

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

We always import environment, not:

environment.production
environment.uat

Angular's build configuration performs the replacement.


app.ts

import { Component, inject, OnInit } from '@angular/core';
import { ProductService } from './services/product';
import { Product } from './models/product';

@Component({
  selector: 'app-root',
  standalone: true,
  templateUrl: './app.html'
})
export class App implements OnInit {

  private productService = inject(ProductService);

  products: Product[] = [];

  ngOnInit(): void {

    this.productService
      .getProducts()
      .subscribe({
        next: data => {
          this.products = data;
        },
        error: error => {
          console.error(error);
        }
      });
  }
}

app.html

<h1>Products</h1>

@for (product of products; track product.id) {

  <div>
    {{ product.name }} - {{ product.price }}
  </div>

}

app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient()
  ]
};

main.ts

import { bootstrapApplication } from '@angular/platform-browser';

import { App } from './app/app';
import { appConfig } from './app/app.config';

bootstrapApplication(App, appConfig)
  .catch(err => console.error(err));

3. Configure angular.json

The important part is telling Angular which environment file should be used for each configuration.

A simplified configuration could look like this:

{
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "configurations": {

            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.production.ts"
                }
              ]
            },

            "uat": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.uat.ts"
                }
              ]
            },

            "development": {
            }

          }
        }
      }
    }
  }
}

The key feature is:

"fileReplacements"

It tells the Angular build system:

When building this configuration, replace one file with another.


4. Running Different Environments

Development

ng serve

or explicitly:

ng serve --configuration development

Uses:

environment.ts

Therefore:

https://localhost:7001/api

UAT

ng serve --configuration uat

or build it:

ng build --configuration uat

Angular replaces:

environment.ts

with:

environment.uat.ts

Therefore:

https://uat-api.jntech.in/api

Production

ng build --configuration production

Angular replaces:

environment.ts

with:

environment.production.ts

Therefore:

https://api.jntech.in/api

5. How does it work?

The Angular service contains:

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

and:

private apiUrl = `${environment.apiUrl}/products`;

During development:

ProductService
      ↓
environment.ts
      ↓
https://localhost:7001/api

During UAT build:

ProductService
      ↓
environment.ts
      ↓
Angular file replacement
      ↓
environment.uat.ts
      ↓
https://uat-api.jntech.in/api

During production build:

ProductService
      ↓
environment.ts
      ↓
Angular file replacement
      ↓
environment.production.ts
      ↓
https://api.jntech.in/api

So ProductService doesn't need to know which environment is running.


6. Generating Angular Environment Configuration

Angular CLI provides:

ng generate environments

Short form:

ng g environments

This can create the initial environment setup and add the corresponding file replacement configuration.

You can then extend it for environments such as:

Development
SIT
UAT
Production

For example:

environment.ts
environment.sit.ts
environment.uat.ts
environment.production.ts

7. What should be stored in environment configuration?

Typical values include:

export const environment = {
  production: false,

  apiUrl: 'https://localhost:7001/api',

  authApiUrl: 'https://localhost:7002/api',

  loggingEnabled: true,

  applicationName: 'JNTech'
};

Then:

environment.apiUrl

or:

environment.loggingEnabled

8. Important: Don't Store Secrets Here

Angular environment files are not secure secret storage.

Do not put values such as:

export const environment = {
  databasePassword: 'mypassword',
  jwtSecret: 'secret-key',
  sqlConnectionString: '...',
  privateApiKey: '...'
};

Why?

Because Angular runs in the browser.

The compiled JavaScript is downloaded to the user's computer, so values included in the Angular bundle can potentially be inspected.

Therefore:

Angular Environment
        ↓
Public/non-secret configuration

ASP.NET Core / Server
        ↓
Secrets
        ↓
Environment variables / Key Vault / secret store

For example, the Angular application can know:

apiUrl: 'https://api.jntech.in'

But the SQL Server connection string should stay in ASP.NET Core/server-side configuration.


9. Build-Time Configuration vs Runtime Configuration

This is an important advanced distinction.

The standard Angular environment-file approach is primarily build-time configuration.

Suppose you run:

ng build --configuration production

The resulting bundle contains the production values.

If you later want to deploy the same build artifact to UAT and Production with different API URLs, environment file replacement alone is not ideal.

You would normally need:

UAT
 ↓
ng build --configuration uat
 ↓
UAT build

Production
 ↓
ng build --configuration production
 ↓
Production build

For CI/CD scenarios where you want:

Build once
   ↓
Deploy same artifact
   ├── SIT
   ├── UAT
   └── Production

you can use runtime configuration, such as loading a JSON configuration file when the application starts.

For example:

assets/config.json

That is a different pattern from Angular's normal environment-file replacement.


10. Key Points

  • Environment configuration stores values that differ between Development, SIT, UAT, and Production.
  • Angular commonly uses environment files such as:
environment.ts
environment.uat.ts
environment.production.ts
  • Environment configurations can use Angular build file replacements.
  • Application code continues importing:
import { environment } from '../environments/environment';
  • Build with:
ng build --configuration production
  • UAT can use:
ng build --configuration uat
  • API base URLs are a common environment-specific setting.
  • Angular environment values are included in client-side code, so do not store secrets in them.
  • Environment files are primarily a build-time configuration technique.
  • Runtime configuration is preferable when the same Angular build must be deployed to multiple environments with different settings.

Interview Questions and Answers

1. How do you manage environment-specific configuration in Angular?

Angular can use separate environment files and build configurations for Development, UAT, and Production. Angular's fileReplacements configuration selects the appropriate environment values during the build.


2. What is an Angular environment file?

It is a TypeScript file containing environment-dependent configuration values such as API URLs and feature settings.

Example:

export const environment = {
  production: false,
  apiUrl: 'https://localhost:7001/api'
};

3. How do you create Angular environment files?

You can generate the initial environment configuration using:

ng generate environments

Then additional files can be added for environments such as SIT or UAT.


4. How does Angular choose the production environment?

Using the build configuration:

ng build --configuration production

The configured fileReplacements can replace:

environment.ts

with:

environment.production.ts

5. How do you access environment variables inside a service?

Import the environment:

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

Then:

private apiUrl = environment.apiUrl;

6. Can we store passwords or secrets in Angular environment files?

No. Angular code executes in the browser and its compiled files can be inspected. Secrets such as database passwords, private API keys, and signing keys should remain on the server.


7. Where should the ASP.NET Core API URL be stored?

A non-secret API base URL can be stored in Angular environment configuration:

apiUrl: 'https://api.jntech.in/api'

8. What is fileReplacements in Angular?

It tells the Angular build system to replace one source file with another for a particular build configuration.

Example:

"fileReplacements": [
  {
    "replace": "src/environments/environment.ts",
    "with": "src/environments/environment.production.ts"
  }
]

9. Are Angular environment files runtime configuration?

Normally, no. They are primarily build-time configuration because the selected values become part of the generated JavaScript bundle.


10. What is the difference between build-time and runtime Angular configuration?

Build-time configuration:

environment.ts
      ↓
ng build
      ↓
JavaScript bundle contains configuration

Runtime configuration:

Angular application starts
      ↓
Loads config.json / configuration endpoint
      ↓
Gets environment settings

Runtime configuration is especially useful when you want to build Angular once and deploy the same artifact to SIT, UAT, and Production with different API URLs.

← Back to Articles