Keywords: Angular 2 | Router | Base href | APP_BASE_HREF | Error Resolution
Abstract: This article thoroughly examines the common error in Angular 2 router caused by an unset base href, offering multiple solutions from adding a base element to using the APP_BASE_HREF token, and analyzes implementation differences across Angular versions. With code examples and error analysis, it helps developers deeply understand routing mechanisms and configuration essentials to ensure application stability.
Problem Background and Error Analysis
In Angular 2 application development, many developers encounter a common error: EXCEPTION: Error during instantiation of LocationStrategy! (RouterOutlet -> Router -> Location -> LocationStrategy), with the root cause being No base href set. This error typically occurs during application startup when the router attempts to initialize the location strategy but finds no valid base URL configuration.
The error stack trace shows that PathLocationStrategy throws a BaseException during instantiation, explicitly stating the need to set the APP_BASE_HREF token or add a base element to the document. This stems from the Angular router's design: it relies on the base href to resolve relative paths, ensuring correct navigation and link generation. Without it, the router cannot determine the application's root path, leading to instantiation failure.
Core Solutions: Setting the Base href
The core solution to this problem is to provide a base URL, which Angular supports via two main methods: using an HTML base element or the APP_BASE_HREF token. The base href defines the static part of the URL, with the router modifying only the remaining portion for seamless navigation.
Method 1: Adding a Base Element to HTML
The simplest approach is to add a base element in the HTML document's <head> section. For example, if the application root is /, add:
<head>
<base href="/">
...
</head>This informs the Angular router that the base path is the root directory, suitable for most single-page applications. Ensure the href value matches the deployment environment; if the app is deployed in a subpath (e.g., /my-app/), set it to <base href="/my-app/">.
Method 2: Using the APP_BASE_HREF Token
For more flexible configuration, use the APP_BASE_HREF token during Angular bootstrap. Implementation varies by Angular version, so choose the appropriate method based on your version.
Angular 2 RC.6 and Later
Set it in the providers array of @NgModule:
import { APP_BASE_HREF } from '@angular/common';
@NgModule({
declarations: [AppComponent],
imports: [RouterModule], // or custom routing module
providers: [{ provide: APP_BASE_HREF, useValue: '/' }]
})
export class AppModule {}This method allows dynamic configuration of the base href, ideal for multi-environment deployments.
Angular 2 RC.0 to RC.5
Use the bootstrap function and provide the token:
import { APP_BASE_HREF } from '@angular/common';
import { bootstrap } from '@angular/platform-browser-dynamic';
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
{ provide: APP_BASE_HREF, useValue: '/' }
]);Angular 2 beta.17 to RC.0
The import path changes slightly:
import { APP_BASE_HREF } from 'angular2/platform/common';
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
{ provide: APP_BASE_HREF, useValue: '/' }
]);Angular 2 Before beta.17
Use the angular2/router module:
import { APP_BASE_HREF } from 'angular2/router';
import { provide } from 'angular2/core';
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
provide(APP_BASE_HREF, { useValue: '/' })
]);Note: In older versions, the provide function is used for dependency injection, while newer versions use object literals.
Error Scenario and Code Example Analysis
Referring to the Q&A code, the developer used Angular 2 beta and defined a basic route configuration:
import { Component } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES } from 'angular2/router';
import { LoginComponent } from './pages/login/login.component';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
@Component({
selector: 'app',
directives: [ROUTER_DIRECTIVES],
template: `
<div class="wrapper">
<router-outlet></router-outlet>
</div>`
})
@RouteConfig([
{ path: '/', redirectTo: '/dashboard' },
{ path: '/login', name: 'login', component: LoginComponent },
{ path: '/dashboard', name: 'dashboard', component: DashboardComponent }
])
export class AppComponent {}This code structure is correct but lacks base href setup. In beta versions, add a base element or use APP_BASE_HREF. For example, add <base href="/"> to HTML, or modify the bootstrap code:
import { APP_BASE_HREF } from 'angular2/router';
import { provide } from 'angular2/core';
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
provide(APP_BASE_HREF, { useValue: '/' })
]);This resolves the error and ensures proper router initialization.
Additional Knowledge and Best Practices
Beyond base href setup, other points deserve attention. The reference article notes that in Angular 2, an empty href attribute (e.g., <a href="">My Link</a>) navigates to the application base URL, differing from Angular 1.x where it might do nothing. Angular 2 interprets empty href as a relative path, resolved based on the base href.
To avoid unintended navigation, consider:
- Always set an explicit base href, avoiding reliance on defaults.
- Use full paths or route names in links instead of empty values.
- Test base URLs across different environments for consistency.
For instance, use router links instead of plain a tags:
<a [routerLink]="['/login']">Login</a>This leverages Angular's router to generate correct URLs, reducing errors.
Summary and Recommendations
Setting the base href is crucial for Angular 2 router functionality. Prefer the base element for simple setups or APP_BASE_HREF for dynamic needs. Choose the correct import and provision method based on your Angular version. In practice, combine error logs and documentation to quickly identify issues. Through this in-depth analysis and code examples, developers can effectively resolve similar routing errors and enhance application stability.