251

What is the method for redirecting the user to a completely external URL in Angular 2. For example, if I need to redirect the user to an OAuth2 server in order to authenticate, how would I do that?

Location.go(), Router.navigate(), and Router.navigateByUrl() are fine for sending the user to another section (route) within the Angular 2 app, but I can't see how they could be used to redirect to an external site?

Michael Oryl
  • 19,602
  • 14
  • 73
  • 113
  • 4
    Don't you find it ridiculous that this is not easily done? There has to be a simpler way to do this, without having to code for it. – Maccurt Jan 23 '18 at 16:39
  • 9
    Note: If your external URL doesn't contain http:// or https://, Angular 4 will treat the URL as an internal route. In case anyone else is struggling with that. – aherocalledFrog Apr 05 '18 at 20:27
  • @aherocalledFrog your comment saved my day. thx! – hyena Sep 01 '21 at 11:16

14 Answers14

303

You can use this-> window.location.href = '...';

This would change the page to whatever you want..

Zoe stands with Ukraine
  • 25,310
  • 18
  • 114
  • 149
Dennis Smolek
  • 7,960
  • 6
  • 29
  • 38
  • 3
    Ugh, I tried calling it as a function for some reason rather than just changing the value. Setting the value directly works. – Michael Oryl Dec 17 '15 at 18:15
  • 12
    Just remember that directly referencing the window will limit your code to platforms with a window object. – ender Oct 26 '16 at 15:08
  • 2
    @ender isn't there an alternative to it? There might be scenarios where we genuinely want to redirect to external links. Sure, we can use window.location.href, but like you say, it has its disadvantages. If there is a supported API in Angular, that would help better. – Krishnan May 07 '17 at 21:05
  • 1
    Sure, but that is 99% of all platforms that run javascript and need to do a page redirect. Even phantom/casperJs respect the window object. You can call `document.location.href` or even `Location.href` as they all refer to the same object. [Location Reference](https://developer.mozilla.org/en-US/docs/Web/API/Location) – Dennis Smolek May 08 '17 at 01:33
  • 2
    @DennisSmolek But if you try to compile this into an android app using Universal, wouldn't this behavior fail? – ender May 12 '17 at 13:50
  • @ender what do you mean "Universal?" NativeScript doesn't have *window* that's true, but it also wouldn't be used to 'redirect' anything like the OP asked. You'd call a webview or an external app if you wanted a site and you'd use the router for internal pages. Windows Universal Platform (UWP) respects window, so does Ionic & Cordova. – Dennis Smolek May 12 '17 at 20:28
  • @DennisSmolek, I believe ender means [angular universal](https://github.com/angular/universal), server side rendering. Is there a "safe" way to navigate to external URL in angular? – William Lohan Sep 11 '17 at 21:38
  • Not trying to be rude, I'm trying to understand, so to be clear @WilliamLohan, you're saying in the Angular Universal app for server side rendering that you want the angular compiler to render all the native pages and views, then also render a different website altogether? I don't think that's ever a situation the server-side would handle either. Serverside rendering still produces HTML, and your user would still use a browser to consume it so a basic link or `location.href`would still likely be the way to go... – Dennis Smolek Sep 25 '17 at 21:57
  • @DennisSmolek you are right that would be a bad design, but I've always been under the impression that in general it is bad practice to use the window object in angular because if it is possible for that code to run while server side rendering you'd get an undefined. So you'd think they'd have a solution. – William Lohan Oct 02 '17 at 15:13
  • any way using `routerLink` ? – Pardeep Jain Mar 26 '18 at 07:04
  • `Binding to event property 'onclick' is disallowed for security reasons, please use (click)=...` – Toolkit Jul 02 '18 at 16:16
  • @DennisSmolek can you help me to solve this question? If i developed login in Angular6 and after login if user have admin permissions he should redirect to Laravel (5.5) backend. then angular frontend and laravel backend should know who is logged now.can u help me to solve this. – RuwanthaSameera Mar 19 '19 at 09:54
  • 1
    @DennisSmolek wouldn't it make testing of method with `window` reference more difficult? – Eugene Jul 16 '19 at 12:26
  • @Eugene correct, without the usage of any dependency, it's really hard to do. A better solution is proposed by Brian (https://stackoverflow.com/a/42452665/2158015) such that you can provide a mock object instead of the actual document. – Didii Jan 29 '20 at 13:05
  • I tried to use this as a relative URL using a proxy but didn't work for me. Later, I had to use the original IP. – Ashraful Sep 08 '21 at 12:11
191

An Angular approach to the methods previously described is to import DOCUMENT from @angular/common (or @angular/platform-browser in Angular < 4) and use

document.location.href = 'https://stackoverflow.com';

inside a function.

some-page.component.ts

import { DOCUMENT } from '@angular/common';
...
constructor(@Inject(DOCUMENT) private document: Document) { }

goToUrl(): void {
    this.document.location.href = 'https://stackoverflow.com';
}

some-page.component.html

<button type="button" (click)="goToUrl()">Click me!</button>

Check out the platformBrowser repo for more info.

Ollie
  • 1,501
  • 1
  • 12
  • 29
Brian
  • 2,235
  • 1
  • 15
  • 21
  • Would the target site know that the request is coming from our app, since the requirement here is to redirect for login purpose and hence the SSO app should redirect back to our app after success – NitinSingh Jun 11 '17 at 20:51
  • 5
    In angular 4, DOCUMENT should be imported from `@angular/common` (i.e. `import { DOCUMENT } from '@angular/common';`), but otherwise this works great! See https://github.com/angular/angular/blob/master/packages/platform-browser/src/dom/dom_tokens.ts – John Oct 23 '17 at 21:21
  • 4
    what is the purpose of injecting document this way `@Inject(DOCUMENT) private document: any` – Sunil Garg Nov 22 '17 at 12:48
  • 3
    @SunilGarg Injecting `DOCUMENT` makes it easier to replace the document object with a mock in unit tests. It also allows for an alternative implementation to be used on other platforms (server/mobile). – eppsilon Mar 14 '18 at 21:35
  • This works great with SSR(ng universal) as well. Thanks! – Poulad Oct 07 '18 at 17:36
  • how do I redirect with params? e.g. pass `{ company : "test" }` to another url which is angular app – Nitin S Mar 06 '19 at 11:44
  • 4
    For strict typing I use, `constructor(@Inject(DOCUMENT) private document: Document) { }` – Ian Jamieson May 29 '19 at 01:37
  • I am getting the error: ERROR NullInjectorError: R3InjectorError(AppModule)[Document -> Document -> Document]: NullInjectorError: No provider for Document! – Sami Mar 30 '22 at 09:47
42

The solution, as Dennis Smolek said, is dead simple. Set window.location.href to the URL you want to switch to and it just works.

For example, if you had this method in your component's class file (controller):

goCNN() {
    window.location.href='http://www.cnn.com/';
}

Then you could call it quite simply with the appropriate (click) call on a button (or whatever) in your template:

<button (click)="goCNN()">Go to CNN</button>
Community
  • 1
  • 1
Michael Oryl
  • 19,602
  • 14
  • 73
  • 113
26

I think you need à target="_blank", so then you can use window.open :

gotoGoogle() : void {
     window.open("https://www.google.com", "_blank");
}
JustLearning
  • 2,934
  • 2
  • 33
  • 50
abahet
  • 9,487
  • 3
  • 31
  • 22
14

If you've been using the OnDestry lifecycle hook, you might be interested in using something like this before calling window.location.href=...

    this.router.ngOnDestroy();
    window.location.href = 'http://www.cnn.com/';

that will trigger the OnDestry callback in your component that you might like.

Ohh, and also:

import { Router } from '@angular/router';

is where you find the router.

---EDIT--- Sadly, I might have been wrong in the example above. At least it's not working as exepected in my production code right now - so, until I have time to investigate further, I solve it like this (since my app really need the hook when possible)

this.router.navigate(["/"]).then(result=>{window.location.href = 'http://www.cnn.com/';});

Basically routing to any (dummy) route to force the hook, and then navigate as requested.

Henry Arousell
  • 159
  • 1
  • 5
  • Thanks a lot for this solution. I was searching for some time for a solution and managed only to open an external link on a new tab, but on same tab all the window.open, location.pathname/href.... didn't let me to navigate away from my site. This is the most clean and correct way to handle routing out of the angular app! – EranKT Feb 03 '22 at 08:24
11

in newer versions of Angular with window as an any

(window as any).open(someUrl, "_blank");
WizardsOfWor
  • 2,636
  • 26
  • 23
5

I used window.location.href='http://external-url';

For me the the redirects worked in Chrome, but didn't work in Firefox. The following code resolved my problem:

window.location.assign('http://external-url');
naveen
  • 51,042
  • 46
  • 158
  • 241
Laura Chesches
  • 2,253
  • 18
  • 15
5

After ripping my head off, the solution is just to add http:// to href.

<a href="http://www.URL.com">Go somewhere</a>
Joel
  • 307
  • 4
  • 3
4

I did it using Angular 2 Location since I didn't want to manipulate the global window object myself.

https://angular.io/docs/ts/latest/api/common/index/Location-class.html#!#prepareExternalUrl-anchor

It can be done like this:

import {Component} from '@angular/core';
import {Location} from '@angular/common';
@Component({selector: 'app-component'})
class AppCmp {
  constructor(location: Location) {
    location.go('/foo');
  }
}
  • 1
    For me, this just changes the URL and the app state doesn't change (actual route looks the same). Even 'location.replaceState('/') did not act as I expected. `router.navigate(['/']);` is what did it for me. – Matt Rowles Nov 03 '16 at 22:54
  • 2
    Angular 2 Location doesn't sound applicable. The docs state that the purpose of location is: "Location is responsible for normalizing the URL against the application's base href." Using this to redirect to a URL within the application may be appropriate; using it to redirect to an external URL doesn't seem to fit with docs. – J. Fritz Barnes Feb 04 '17 at 00:14
4

You can redirect with multiple ways:

like

window.location.href = 'redirect_url';

another way Angular document:

import document from angular and the document must be inject as well as bellow otherwise you will get error

import { DOCUMENT  } from '@angular/common';
export class AppComponent {
     constructor(
       @Inject(DOCUMENT) private document: Document
    ) {}
   this.document.location.href = 'redirect_url';
}
Siraj Ali
  • 449
  • 3
  • 10
2

There are 2 options:

  1. if you want to redirect in same window/tab

     gotoExternalDomain(){
         window.location.href='http://google.com/'
     }
    
  2. if you want to redirect in new tab

     gotoExternalDomain(){
         (window as any).open("http://google.com/", "_blank");
     }
    
sravan ganji
  • 3,997
  • 3
  • 19
  • 32
1

None of the above solutions worked for me, I just added

window.location.href = "www.google.com"
event.preventDefault();

This worked for me.

Or try using

window.location.replace("www.google.com");
Rishi0405
  • 324
  • 1
  • 10
-1

In your component.ts

import { Component } from '@angular/core';

@Component({
  ...
})
export class AppComponent {
  ...
  goToSpecificUrl(url): void {
    window.location.href=url;
  }

  gotoGoogle() : void {
    window.location.href='https://www.google.com';
  }
}

In your component.html

<button type="button" (click)="goToSpecificUrl('http://stackoverflow.com/')">Open URL</button>
<button type="button" (click)="gotoGoogle()">Open Google</button>

<li *ngFor="item of itemList" (click)="goToSpecificUrl(item.link)"> // (click) don't enable pointer when we hover so we should enable it by using css like: **cursor: pointer;**
Linh
  • 51,033
  • 19
  • 228
  • 256
-2

Just simple as this

window.location.href='http://www.google.com/';
Akitha_MJ
  • 3,156
  • 20
  • 16