226

I am getting an error and can't find why. Here is the error:

EXCEPTION: Error during instantiation of LocationStrategy! (RouterOutlet -> Router -> Location -> LocationStrategy).
    angular2.dev.js:23514 EXCEPTION: Error during instantiation of LocationStrategy! (RouterOutlet -> Router -> Location -> LocationStrategy).BrowserDomAdapter.logError @ angular2.dev.js:23514BrowserDomAdapter.logGroup @ angular2.dev.js:23525ExceptionHandler.call @ angular2.dev.js:1145(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:141(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494(anonymous function) @ angular2-polyfills.js:243microtask @ angular2.dev.js:5751run @ angular2-polyfills.js:138(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305
    angular2.dev.js:23514 ORIGINAL EXCEPTION: No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.BrowserDomAdapter.logError @ angular2.dev.js:23514ExceptionHandler.call @ angular2.dev.js:1154(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:141(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494(anonymous function) @ angular2-polyfills.js:243microtask @ angular2.dev.js:5751run @ angular2-polyfills.js:138(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305
    angular2.dev.js:23514 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:23514ExceptionHandler.call @ angular2.dev.js:1157(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:141(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494(anonymous function) @ angular2-polyfills.js:243microtask @ angular2.dev.js:5751run @ angular2-polyfills.js:138(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305
    angular2.dev.js:23514 Error: No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.
        at new BaseException (angular2.dev.js:8080)
        at new PathLocationStrategy (router.dev.js:1203)
        at angular2.dev.js:1380
        at Injector._instantiate (angular2.dev.js:11923)
        at Injector._instantiateProvider (angular2.dev.js:11859)
        at Injector._new (angular2.dev.js:11849)
        at InjectorDynamicStrategy.getObjByKeyId (angular2.dev.js:11733)
        at Injector._getByKeyDefault (angular2.dev.js:12048)
        at Injector._getByKey (angular2.dev.js:12002)
        at Injector._getByDependency (angular2.dev.js:11990)

Does anyone know why the router is throwing this? I am using angular2 beta

here is my code:

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 {
}
HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Jason Spick
  • 6,028
  • 13
  • 40
  • 59

8 Answers8

411

https://angular.io/docs/ts/latest/guide/router.html

Add the base element just after the <head> tag. If the app folder is the application root, as it is for our application, set the href value exactly as shown here.

The <base href="/"> tells the Angular router what is the static part of the URL. The router then only modifies the remaining part of the URL.

<head>
  <base href="/">
  ...
</head>

Alternatively add

>= Angular2 RC.6

import {APP_BASE_HREF} from '@angular/common';

@NgModule({
  declarations: [AppComponent],
  imports: [routing /* or RouterModule */], 
  providers: [{provide: APP_BASE_HREF, useValue : '/' }]
]); 

in your bootstrap.

In older versions the imports had to be like

< Angular2 RC.6

import {APP_BASE_HREF} from '@angular/common';
bootstrap(AppComponent, [
  ROUTER_PROVIDERS, 
  {provide: APP_BASE_HREF, useValue : '/' });
]); 

< RC.0

import {provide} from 'angular2/core';
bootstrap(AppComponent, [
  ROUTER_PROVIDERS, 
  provide(APP_BASE_HREF, {useValue : '/' });
]); 

< beta.17

import {APP_BASE_HREF} from 'angular2/router';

>= beta.17

import {APP_BASE_HREF} from 'angular2/platform/common';

See also Location and HashLocationStrategy stopped working in beta.16

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 3
    Little example of second way: `bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue : '/'})]);` – malloc4k Jan 04 '16 at 18:23
  • 2
    I had to add the import line `import {provide} from 'angular2/core';` to be able to use provide. – CorayThan Jan 12 '16 at 23:35
  • 2
    I had to import line `import {APP_BASE_HREF} from 'angular2/router';` – jimmystormig Feb 04 '16 at 15:22
  • Thanks for the updates. I don't use TS myself (only Dart) and my TS knowledge is still limited. – Günter Zöchbauer Feb 04 '16 at 15:27
  • I strongly recommend to include project directory structure here to make it more clear. I made an error by just include in my project, because of the different project directory structure. It took me some time to figure out the reason. – Ng2-Fun Feb 29 '16 at 16:04
  • What's you Project structure. `/` is common, for specific cases this might need a different path. – Günter Zöchbauer Feb 29 '16 at 16:06
  • as of this day, (january 14th 2017), works fine for me, except when trying to test my app using TestBed. In this case, I have to provide a APP_BASE_HREF – Noone Jan 14 '17 at 17:02
  • @JCorriveau yes, it's supposed to work. Only when you serve the application on a subdirectory like `http://example.org/somesub/index.html` or similar, then you need a different path like `base="/somesub"` – Günter Zöchbauer Jan 14 '17 at 17:04
  • 1
    My project has SVG elements filled with image patterns. The images were never displayed in Firefox when `` was set in the file (for `"/"`, `"./"`, `"#"` or any other base path, no matter how the image paths themselves were specified in the pattern). The only solution that finally worked was to use `APP_BASE_HREF` instead. A real life saver! – ConnorsFan Jan 16 '17 at 22:50
  • 1
    hold on, but is exactly the reason why angular builds are unable to be opened just by opening index.html from local folder (without web server)... I don't understand why angular need this base href – Dmitry Gusarov Nov 25 '17 at 09:56
  • I doubt this is related. Angular needs a server because of security constraints in the browser (can be disabled by command line arguments). Angular can instead of `` also be configured with `APP_BASE_HREF` – Günter Zöchbauer Nov 25 '17 at 10:44
  • I want to add to your answer, if you have in your source index.html a tag, it will override any APP_BASE_HREF or ng build --base-href; values. After removng it, I can modify the base href from any means. – Damjan Dimitrioski Jul 16 '18 at 09:27
  • @DamjanDimitrioski I had expected the opposite. **Inside Angular code** `APP_BASE_HREF` should override ``. `APP_BASE_HREF` doesn't affect other areas where `` has an effect, like SVG refs or similar. – Günter Zöchbauer Jul 16 '18 at 09:38
  • So, what's causing ng build to ignore the APP_BASE_HREF if base href is set in src index.html, in Angular 5.x ? – Damjan Dimitrioski Jul 16 '18 at 10:03
  • @DamjanDimitrioski not sure what you mean with "ignore the APP_BASE_HREF". `APP_BASE_HREF` is only used by Angular code like the router or some custom code that might inject `APP_BASE_HREF`. Perhaps you expect it to have some effect it is not supposed to have? – Günter Zöchbauer Jul 16 '18 at 10:04
  • @GünterZöchbauer I expected setting --base-href /mypath to update the from index.html(source) created the tag in the dist directory. This behaviour was not explained in any docs I read. – Damjan Dimitrioski Jul 16 '18 at 10:29
  • I don't know about `--base-href ...`, but that doesn't seem to be related to `APP_BASE_HREF`, only to `` – Günter Zöchbauer Jul 16 '18 at 10:36
  • This is the right answer. I get this every time I create a new `*.spec.ts` test file. It is always required to build up a complete running environment. – Yoraco Gonzales Nov 24 '18 at 11:35
  • I had this error on a test `.spec.ts` while using `Location`. I add the `RouterTestingModule` and the error goes away – Mcsky Dec 14 '18 at 12:40
  • Using {provide: APP_BASE_HREF, useValue : '/' } worked for me –  Jul 26 '19 at 18:48
  • Not working. Angular modules start throwing NullInjector errors – Roland Jegorov Oct 16 '20 at 11:35
  • does this mean you have to hardcode the base in the index file if you're not using the HashLocationStrategy? this would be a problem when deploying in a context which is not root, isn't there a better solution without having to change the index file? – magomarcelo Dec 11 '20 at 11:05
  • 1
    @magomarcelo You can use string replacement in a build step, or use some JavaScript to change the value before Angular is started for example deriving it from the current location. There are probably other ways I'm not thinking of currently. – Günter Zöchbauer Dec 11 '20 at 16:06
38

I had faced similar issue with Angular4 and Jasmine unit tests; below given solution worked for me

Add below import statement

import { APP_BASE_HREF } from '@angular/common';

Add below statement for TestBed configuration:

TestBed.configureTestingModule({
    providers: [
        { provide: APP_BASE_HREF, useValue : '/' }
    ]
})
Dilip Nannaware
  • 1,410
  • 1
  • 16
  • 24
15

Angular 7,8 fix is in app.module.ts

import {APP_BASE_HREF} from '@angular/common';

inside @NgModule add

providers: [{provide: APP_BASE_HREF, useValue: '/'}]

Feng Zhang
  • 1,698
  • 1
  • 17
  • 20
  • 1
    I faced this error while trying to load a component for angular story book. This component had router dependency. It solved the error!! – Arpan Banerjee Jun 01 '20 at 10:34
12

You can also use hash-based navigation by including the following in app.module.ts

import { LocationStrategy, HashLocationStrategy } from '@angular/common';

and by adding the following to the @NgModule({ ... })

@NgModule({
  ...
  providers:    [
      ProductService, {
          provide: LocationStrategy, useClass: HashLocationStrategy
      }
  ],
  ...
})

Angular 2 Development with TypeScript

“HashLocationStrategy—A hash sign (#) is added to the URL, and the URL segment after the hash uniquely identifies the route to be used as a web page fragment. This strategy works with all browsers, including the old ones.”

Excerpt From: Yakov Fain Anton Moiseev. “Angular 2 Development with TypeScript.”

Lionel Morrison
  • 566
  • 4
  • 15
  • Thanks Lionel! This is excellent and solved a problem I had using the APP_BASE_HREF solution above which fails when using url parameters like "product/:id". Thanks! – Stokely Mar 25 '20 at 06:21
8

Since 2.0 beta :)

import { APP_BASE_HREF } from 'angular2/platform/common';
Gustavo Morales
  • 2,614
  • 9
  • 29
  • 37
Aastal
  • 350
  • 2
  • 8
  • As of Rc6 this is all in the provider now: https://angular.io/docs/ts/latest/api/common/index/APP_BASE_HREF-let.html – Mark Kenny Sep 16 '16 at 09:50
  • 1
    This helped me when my spec in Karma was failing with Error: No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document. – AlignedDev Dec 02 '16 at 20:03
7

it is just that add below code in the index.html head tag

   <html>
    <head>
     <base href="/">
      ...

that worked like a charm for me.

naram kiran
  • 109
  • 1
  • 4
6

With angular 4 you can fix this issue by updating app.module.ts file as follows:

Add import statement at the top as below:

import {APP_BASE_HREF} from '@angular/common';

And add below line inside @NgModule

providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]

Reff: https://angular.io/api/common/APP_BASE_HREF

Suresh Kamrushi
  • 15,627
  • 13
  • 75
  • 90
2

Check your index.html. If you have accidentally removed the following part, include it and it will be fine

<base href="/">

<meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
Tadele Ayelegn
  • 4,126
  • 1
  • 35
  • 30