In Angular v15 we finally saw the introduction of standalone components.
With @NgModule
being an optional choice, this brings some changes as to how we create routes and routing definitions.
There is also lazy loading standalone components to consider.
But before we get there, how can we create routes with standalone components in Angular?
First we need to bootstrap the Angular application. I’ve already written an in-depth guide to bootstrapping a standalone Angular app so we won’t go into things too deep, we’ll just cover what we need.
Let’s start with a simple App
component and bootstrap it via bootstrapApplication
:
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
@Component({
selector: 'my-app',
standalone: true,
template: `
Hello Angular!
`,
})
export class App {}
bootstrapApplication(App);
Before standalone components, we would use the RouterModule.forRoot()
method and pass in our routing configuration.
So, how do we migrate across to the new standalone style whilst maintaining our routing?
Let’s assume we have the following routes:
import { Route } from '@angular/router';
import { ProductsComponent } from '../products.component';
import { ProductComponent } from './product.component';
export const routes: Route[] = [
{
path: '',
component: ProductsComponent,
},
{
path: ':id',
component: ProductComponent,
},
{
path: '**',
redirectTo: '',
},
];
We now need to import a new function provideRouter and pass it into the providers
on the bootstrapApplication
call:
import { Component } from '@angular/core';
import { provideRouter } from '@angular/router';
import { bootstrapApplication } from '@angular/platform-browser';
import { routes } from './routes';
@Component({
selector: 'my-app',
standalone: true,
template: `
Hello Angular!
`,
})
export class App {}
bootstrapApplication(App, {
providers: [provideRouter(routes)],
});
💯 Using
provideRouter
is the “standalone way”, which avoids importingRouterModule
entirely. For all Directives that theRouterModule
would expose, you need to import them per standalone component.
That’s great for now, but we need a <router-outlet>
now to render our components!
As we’re using standalone components, we’ll need to import the RouterOutlet
directive and add it to the component imports
metadata:
import { Component } from '@angular/core';
import { provideRouter, RouterOutlet } from '@angular/router';
import { bootstrapApplication } from '@angular/platform-browser';
import { routes } from './routes';
@Component({
selector: 'my-app',
standalone: true,
imports: [RouterOutlet],
template: `
<router-outlet></router-outlet>
`,
})
export class App {}
bootstrapApplication(App, {
providers: [provideRouter(routes)],
});
What I love about this new way to provide routing is that we don’t need to create an @NgModule
for every single routing configuration. So if you’ve been doing that, it’s time to refactor!
Here’s a live code example for you to try out:
And that’s it! You can pass in your routes
into provideRouter
which makes them available to our app - just don’t forget to import your RouterOutlet
and any other directives you’re using.
🏆 Check out my brand new Angular v15 course where you’ll learn Angular, TypeScript, RxJS and state management principles from beginning to expert level.
Happy routing!