If a UI must talk to a different API in each region, building a separate bundle per region is slow and means the artefact you tested is not the one you deploy. Build once and read configuration at runtime.
Put a small file in the app’s public folder, public/config.json:
{ "apiUrl": "http://localhost:3000" }
Load it before the app starts, in main.ts:
fetch('/config.json', { cache: 'no-store' })
.then(r => r.json())
.then(cfg => bootstrapApplication(AppComponent, {
providers: [
{ provide: APP_CONFIG, useValue: cfg },
provideHttpClient(),
],
}));
Components and interceptors inject APP_CONFIG and prefix requests with cfg.apiUrl.
The pipeline then builds one artefact, and each region’s deploy replaces only config.json. Serve config.json with Cache-Control: no-cache, because a cached copy would send users to the wrong API.
Compare with Angular’s fileReplacements in angular.json: that swaps environment files at build time, which forces a rebuild per region. Keep runtime config for URLs and feature flags, and never put secrets in files shipped to a browser.