How to redirect to an external URL from angular2 route without using component?

I would like to create an external redirect, but to make all routes consistent I think it would be nice to do everything(including external redirects) under Router States configuration.

so:

const appRoutes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'first', component: FirstComponent},
  {path: 'second', component: SecondComponent},
  {path: 'external-link', /*would like to have redirect here*/}      
];

UPD: and I don't want to use empty component for this case like @koningdavid suggested. This solution looks really weird for me. It should be something really easy to implement for such case, without virtual components.


You can achieve what you want with a trick using the resolve option of a route. Resolve is some data value that Angular2 will obtain for the route to be initialized. More details you can find here in the official documentation.

I have tried this approach and it does work. Example:

Add this to the provider section (plus import the required classes from Routing)

@NgModule({
    providers: [
        {
            provide: 'externalUrlRedirectResolver',
            useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
            {
                window.location.href = (route.data as any).externalUrl;
            }
        }
    ]
})

Then you can define your route like this:

{
        path: 'test',
        component: AnyRandomComponent,
        resolve: {
            url: 'externalUrlRedirectResolver'
        },
        data: {
            externalUrl: 'http://www.google.com'
        }
    }

This will redirect to the external URL. It's a bit of a hackish way really. I tried to achieve the result without using the component at all, but you have to use either redirectTo or component or children or loadChildren. redirectTo won't trigger the resolve and I am not sure about children, though you can experiment.

You can implement it in a nice class rather than direct function in provider. More info in the documentation (see reference above).

P.S. I would really rather use a redirect component myself I think. Just use the trick with the data and getting the state from the router with externalUrl to get this as a parameter.


You can create a RedirectGuard:

import {Injectable} from '@angular/core';
import {CanActivate, ActivatedRouteSnapshot, Router, RouterStateSnapshot} from '@angular/router';

@Injectable({
    providedIn: 'root'
})
export class RedirectGuard implements CanActivate {

  constructor(private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

      window.location.href = route.data['externalUrl'];
      return true;

  }
}

Import it in app.module:

providers: [RedirectGuard],

And define your route:

{
     path: 'youtube',
     canActivate: [RedirectGuard],
     component: RedirectGuard,
     data: {
       externalUrl: 'https://www.youtube.com/'
     }
 }

As far as I know NG2 router doesn't support external redirecting. You could create a redirect component as a workaround.

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

@Component({
  selector: 'redirect',
  template: 'redirecting...'
})
export class RedirectComponent implements OnInit {
  constructor() { }

  ngOnInit() {
    window.location.href = 'http://www.redirecturl.com'
  }
}

And use that in your routing

{ path: 'login', component: RedirectComponent, pathmath: 'full'},

Hmm...

I think you can simply request the URL instead of calling ng2 Router...


For example...

<a href="http://example.com">External</a>

instead of

<a routerLink="/someRoute" routerLinkActive="active">External</a>

OR

window.location.href = 'http://www.example.com'

instead of

this.router.navigate( [ '/someRoute', 'someParam' ] );

Right...?