Configuring Routes
At the heart of Angular’s router is a single data structure: the Routes array. Each entry maps a URL path to the component (or behaviour) the router should render when that path matches. Getting this configuration right is what makes the difference between a navigable, deep-linkable app and a fragile one. This page covers how to declare the Routes array in a modern standalone app, how path matching actually works, and how to handle redirects and a catch-all 404 page.
The Routes array
A Route is a plain object. The most common form pairs a path string with a component to display. In a standalone application you register the array through provideRouter() in app.config.ts rather than the legacy RouterModule.forRoot().
import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';
export const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
];
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes)],
};
Notice the leading slash is never part of a path value. The router treats every path as relative to its position in the tree, so '' is the empty (root) path and 'about' matches /about.
How path matching works
The router walks the Routes array top to bottom and uses the first route whose path matches the current URL segment. Order therefore matters: more specific routes must come before more general ones. By default Angular uses pathMatch: 'prefix', meaning a route matches if the URL starts with the configured path.
pathMatch value | Matches when… | Typical use |
|---|---|---|
'prefix' (default) | the URL begins with the path | most routes, parent layouts |
'full' | the entire URL equals the path | empty-path redirects |
This prefix behaviour is why an empty path '' is dangerous in a redirect without pathMatch: 'full' — '' is a prefix of every URL, so a prefix match would redirect everything.
export const routes: Routes = [
{ path: 'products', component: ProductListComponent },
{ path: 'products/featured', component: FeaturedComponent },
];
Tip: Both routes above work because
pathsegments are matched segment-by-segment, not as raw string prefixes —'products'will not swallow/products/featured. The ordering caveat matters most for redirects and the wildcard route, covered below.
Redirecting routes
Use redirectTo to forward one path to another. The classic case is sending the empty root URL to a default landing page.
export const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'settings', component: SettingsComponent },
];
The pathMatch: 'full' is essential here. Without it, the empty-path prefix would match every navigation and trap the user on /dashboard permanently. You can also redirect legacy paths to keep old bookmarks alive:
{ path: 'home', redirectTo: 'dashboard', pathMatch: 'full' },
For dynamic redirects, redirectTo can be a function (Angular 18+) that receives the matched route data and returns a path or a UrlTree.
import { redirectTo } from '@angular/router';
{
path: 'legacy/:id',
redirectTo: ({ params }) => `/items/${params['id']}`,
},
The wildcard route for 404s
The double-asterisk path ** matches any URL the router has not already matched. Because matching stops at the first hit, this route must be the last entry in the array — otherwise it would intercept everything.
import { Routes } from '@angular/router';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
export const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'settings', component: SettingsComponent },
{ path: '**', component: PageNotFoundComponent },
];
Navigating to an unknown URL such as /nonsense now renders your 404 component instead of leaving the outlet empty. You can confirm the resolved route at runtime by inspecting the router’s recognized URL.
import { Component, inject } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs';
@Component({ selector: 'app-root', standalone: true, template: `<router-outlet />` })
export class AppComponent {
constructor() {
const router = inject(Router);
router.events
.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd))
.subscribe((e) => console.log('Navigated to:', e.urlAfterRedirects));
}
}
Output:
Navigated to: /dashboard
Navigated to: /settings
Navigated to: /nonsense
The final line shows the wildcard route activating: the URL stays /nonsense in the address bar while the 404 component renders in the outlet.
Warning: A
**route placed anywhere but last will short-circuit every route declared after it, silently breaking navigation. Keep it as the final element, and put redirects above the routes they target.
Attaching static data and titles
Each route can carry a data object and a title. The title is applied to the document automatically by Angular’s built-in title strategy.
{
path: 'settings',
component: SettingsComponent,
title: 'Settings · MyApp',
data: { requiresAuth: true },
},
Best practices
- Register routes with
provideRouter(routes)inapp.config.tsfor standalone apps rather thanRouterModule.forRoot(). - Keep the
Routesarray ordered from most specific to least specific, and always place the**wildcard route last. - Use
pathMatch: 'full'on every empty-path ('') redirect to avoid an infinite or unintended match. - Never start a
pathvalue with a leading slash; paths are relative to their position in the route tree. - Provide a wildcard
**route mapped to a dedicated 404 component so unknown URLs fail gracefully. - Add a
titleto top-level routes to keep the browser tab and history meaningful for users.