Complete Solution for Dynamically Setting base href in Angular 2+

Nov 25, 2025 · Programming · 9 views · 7.8

Keywords: Angular | base href | dynamic path

Abstract: This article provides a comprehensive solution for dynamically setting the base href in Angular 2+ enterprise applications. Addressing resource loading issues caused by URL path variations in multi-tenant scenarios, it details a standardized implementation using APP_BASE_HREF, with full code examples and configuration guidelines to ensure stable operation across different environments.

In enterprise Angular 2+ application development, it is common to encounter scenarios where unique URL paths are required for different customers. For instance, customer one might access the application via https://our.app.com/customer-one, while customer two uses https://our.app.com/customer-two. Correctly setting the <base href> tag is critical here, as it determines the base URL for resolving all relative URLs. Improper configuration can lead to resource loading failures when users refresh the page or directly access deep links, severely impacting user experience.

Problem Analysis

The initial dynamic setup involved directly manipulating the DOM in index.html to insert the <base href> tag. For example, when a user visits https://our.app.com/customer-two/another-page, a script would set the base href to /customer-two/another-page, causing Angular to fail in loading resources from the root path. The core issue lies in the path extraction logic being insufficiently precise, failing to derive a stable base path.

Core Solution

Angular provides the APP_BASE_HREF token, allowing dynamic injection of the base path during application bootstrap. Below is the complete implementation based on best practices.

Step 1: Modify index.html

Add the following code at the very beginning of the <head> section in index.html. This sets a default base href to "/" and uses JavaScript to extract the dynamic path, storing it in a global variable.

<base href="/">
<script>
  (function() {
    window['_app_base'] = '/' + window.location.pathname.split('/')[1];
  })();
</script>

This code uses window.location.pathname.split('/')[1] to accurately extract the first segment of the path (e.g., customer-two) and constructs the full base path.

Step 2: Configure AppModule

In app.module.ts, import the necessary modules and tokens, and configure APP_BASE_HREF in the providers array.

import { NgModule, enableProdMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { APP_BASE_HREF } from '@angular/common';

import { AppComponent, routing, appRoutingProviders, environment } from './';

if (environment.production) {
  enableProdMode();
}

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    HttpModule,
    routing
  ],
  bootstrap: [AppComponent],
  providers: [
    appRoutingProviders,
    { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' },
  ]
})

export class AppModule { }

Here, useValue: window['_app_base'] || '/' ensures fallback to the default path if the global variable is undefined, enhancing code robustness.

Advanced Optimization

To improve maintainability and modularity, encapsulate the path extraction logic into a standalone utility function. Drawing from other answers, create a getBaseLocation function.

export function getBaseLocation(): string {
  const paths: string[] = window.location.pathname.split('/').splice(1, 1);
  const basePath: string = (paths && paths[0]) || 'default-customer';
  return '/' + basePath;
}

Then, use the useFactory provider in AppModule to dynamically invoke this function.

providers: [
  appRoutingProviders,
  {
    provide: APP_BASE_HREF,
    useFactory: getBaseLocation
  },
]

This approach avoids embedding scripts in index.html, resulting in cleaner code structure and easier unit testing.

Build-Time Configuration

In addition to runtime dynamic setting, the baseHref can be specified during build time using Angular CLI. For example, the command ng build --base-href /customer-two/ directly modifies the base path in generated files. This method is suitable for fixed-environment scenarios, such as building separate deployment packages per customer.

Configure baseHref for different environments in angular.json to automate builds.

"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      "baseHref": "/testurl/",
    },
    "configurations": {
      "production": {
        "baseHref": "/productionurl/",
      }
    }
  }
}

Conclusion

By combining runtime dynamic injection and build-time configuration, you can flexibly manage path requirements in multi-tenant Angular applications. The key is to correctly use the APP_BASE_HREF token to ensure accurate resource path resolution. In practice, choose the appropriate solution based on project complexity, prioritizing modular function encapsulation to enhance code quality.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.