How to get base url in angular 5?
My current url is http://localhost:4200/test/dashboard.
I want to print base url i.e http://localhost:4200 using angular 5 features.
Solution 1:
The other answers here cover quite a range of options:
location
window.location
document.location
-
DOCUMENT
/Document
Location
LocationStrategy
PlatformLocation
TLDR; for simple situations the globally available DOM location
may be enough for your needs. However, you probably really want an Angular Location
instance. And, in certain circumstances, LocationStrategy
may also be useful.
You can access the DOM location
directly without needing to import anything:
foo(): void {
console.log(location.origin);
console.log(location.href);
console.log(location.pathname);
}
If you want to use the Angular Location
and LocationStrategy
then you have to pull them in like so:
import { Location, LocationStrategy } from '@angular/common';
constructor(private location: Location, private locationStrategy: LocationStrategy) { }
foo(): void {
console.log(this.location.path());
console.log(this.location.prepareExternalUrl('/'));
console.log(this.locationStrategy.getBaseHref());
}
You can use prepareExternalUrl
to e.g. construct URLs that refer to assets:
const url = this.location.prepareExternalUrl('assets/svg/icons.svg');
If you're serving everything out from directly under /
, there may not seem to be much point using the Angular Location
but if you've set your application's base href to be something other than /
or if you're doing more complicated things with paths then Angular Location
will help you work with this kind of thing correctly.
If prepareExternalUrl
doesn't seem to be picking up your base href, see the notes about this at the end of this answer.
In some examples, you'll see it stated that you have to configure APP_BASE_HREF
in order for things to pick up your base href. This is not the case anymore, see the end of this answer for more on this.
Note: by default Angular uses the location strategy PathLocationStrategy
but if you've changed things to use HashLocationStrategy
then prepareExternalUrl
and other functions will not work the same way. However, if you're using HashLocationStrategy
you probably know what you're doing, so I won't go into this here.
The full details
Let's have a look in turn at each of the entities listed above.
1. location
, window.location
and document.location
are of type Location
, come directly from the DOM and are available as global variables, i.e. you don't have to import or inject them in any way.
These are all ways of getting at the same thing. location
and window.location
are literally the same thing (window
can be referred to explicitly but it is also the implicit global this
). location
and document.location
are essentially the same thing, see this SO answer for more details on this.
You can find the MDN documentation for Location
here.
So if the DOM Location
is all that you want, I would just use location
. Some people like to be explicit that they're accessing the window
object and prefer to use window.location
. The location
field of document
has a confusing history and seems to be the least popular way to access a DOM Location
instance.
2. Elsewhere, you can see people using the Angular dependency injection token DOCUMENT
like so:
import { DOCUMENT } from '@angular/common';
import { Inject } from '@angular/core';
constructor(@Inject(DOCUMENT) private document: Document)
Then you can access this.document.location
. Again, this is simply a DOM Location
instance, so if this is what you want, why bother injecting it when you can access it directly as location
? The this.document
and the globally available document
mentioned above are both of type Document
and, in a browser context, they are the same thing. So the only reason you'd inject it is if you're working in a non-browser context.
You can find the Angular documentation for DOCUMENT
here and the MDN documentation for Document
here.
3. Finally three Angular entities - Location
, LocationStrategy
and PlatformLocation
.
Confusingly, Angular has used the same name for their location type (i.e. Location
) as the type of location
etc. up above. The DOM Location
is available globally and doesn't need to be imported, the Angular Location
needs to be imported from @angular/common
.
The Angular entities Location
, LocationStrategy
and LocationStrategy
are layered on top of each other, a Location
contains a LocationStrategy
and a LocationStrategy
in turn contains a PlatformLocation
. None of them directly exposes the contained entity, i.e. you can't get to the LocationStrategy
via the Location
API nor to the PlatformLocation
via the LocationStrategy
.
You'll see many older examples directly accessing PlatformLocation
but as its documentation makes clear, this "class should not be used directly by an application developer."
Conclusions
So we started with a confusing array of entities but in the end, it really just boils down to choosing between the DOM provided global location
object and the Angular provided Location
object. Under certain circumstances, LocationStrategy
may also be of interest.
Code
But if you want more insight, why not try out the following code that pulls in every one of the entities that have been mentioned. Look at the console output to see what each entity provides and just experiment with the APIs of each. For simplicity just add this code to one of your existing components:
import { Inject } from '@angular/core';
import { DOCUMENT, Location, LocationStrategy, PlatformLocation } from '@angular/common';
// Normally, you should not access PlatformLocation directly, it's just included here for completeness.
constructor(@Inject(DOCUMENT) private document: Document, private location: Location, private locationStrategy: LocationStrategy, private plaformLocation: PlatformLocation) { }
ngOnInit(): void {
// These are just different ways to get the same thing, so if this
// is what want, you might as well use plain location directly.
console.log('DOM location', location)
console.log('DOM window.location', window.location)
console.log('DOM document.location', document.location)
console.log('Injected document.location', this.document.location)
// These are layered on top of each other. A Location contains a
// LocationStrategy and a LocationStrategy contains a PlatformLocation.
// Note that this.location, used here, is a different thing to plain location above.
console.log('location', this.location)
console.log('locationStrategy', this.locationStrategy)
console.log('platformLocation', this.plaformLocation) // PlatformLocation "should not be used directly by an application developer."
}
Open your app in a browser and look at the console output in developer tools and see if you find what you're looking for.
Note: things become stale quickly in the Angular world - the above all worked fine with Angular 9.
Base href and Location
If you have a simple application with no routes and you've set the base href to something other than /
then you may find that functions like prepareExternalUrl
fail to take the base href into account. This happens if you haven't included a RouterModule
in the imports
section of your app.module.ts
. For whatever reason, the LocationStrategy
and PlatformLocation
, that underly Location
, are only properly configured if a RouterModule
is imported. To get around this, just add the following:
imports: [
...
RouterModule.forRoot([]),
...
]
Even though you've specified no routes, i.e. passed in []
, this will properly configure things to take your base href into account.
APP_BASE_HREF
, PlatformLocation
and Location
In some examples, you'll see it stated that you have to explicitly configure APP_BASE_HREF
in order for things to pick up your base href. E.g. like so in app.module.ts
:
providers: [{
provide: APP_BASE_HREF,
useFactory: (pl: PlatformLocation) => pl.getBaseHrefFromDOM(),
deps: [PlatformLocation]
}]
This may have been necessary at some stage but the current PathLocationStrategy
code does this for you automatically, i.e. if you don't set APP_BASE_HREF
then it will itself retrieve the base href value using the getBaseHrefFromDOM()
method of PathLocationStrategy
. You can see this here in the constructor
logic of PathLocationStrategy
.
Solution 2:
No need for angular specific features, window.location.origin
will do it for you.
Solution 3:
console.log(location);
console.log(location.href);
to get base url : console.log(location.origin);
Solution 4:
This doesn't work for me (Angular 7):
this.location.path.name
But I found that it's possible to get it from document:
import { Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
constructor(@Inject(DOCUMENT) private document: Document) {
const origin = this.document.location.origin;
}