iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To add routing in Angular, you define a Routes array that maps URL paths to components, register it with provideRouter(routes), place a <router-outlet /> where routed pages should appear, and use routerLink for navigation. Navigation then happens inside the app without a full-page reload. The steps below follow Angular’s current routing guide, and the sections after them cover route order, nested views, lazy loading, and guards, including what guards cannot protect.
Which setup this guide follows
The examples use standalone components and the provideRouter configuration that Angular’s current routing documentation describes at angular.dev/guide/routing/define-routes. Projects built on NgModules register the same kind of route array through RouterModule instead, so check which architecture your project uses before copying code. Angular also publishes a versioned guide for v20 at v20.angular.dev/guide/routing/define-routes; route matching behaves the same way there, but if your project is on a different major version, read the guide for that version.
Set up routing step by step
- Define the routes. Create a
Routesarray that maps each URL path to a component. In Angular CLI projects, the conventional location issrc/app/app.routes.ts.import { Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { UserComponent } from './user/user.component'; import { NotFoundComponent } from './not-found/not-found.component'; export const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'user/:id', component: UserComponent }, { path: '**', component: NotFoundComponent } ]; - Register the router. In the standalone application configuration (usually
src/app/app.config.ts), addprovideRouter(routes)to the providers array.import { ApplicationConfig } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [provideRouter(routes)] }; - Render the active view. Import
RouterOutletinto the component that should host routed pages, usually the root component, and place<router-outlet />in its template. The router inserts the component that matches the current URL at that point. The Show routes with Outlets guide covers the rendering model in detail.import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', imports: [RouterOutlet], template: ` <nav> <a routerLink="/">Home</a> </nav> <router-outlet /> ` }) export class AppComponent {} - Add navigation with
RouterLink. ImportRouterLinkinto the component and use it on ordinary anchor elements. Angular Router handles the click, so the browser does not request a new page. The Navigate to routes guide explains the declarative approach.<a routerLink="/user/42">View user 42</a> - Add dynamic and nested paths. A colon prefix turns a path segment into a parameter, as in
user/:id. When only part of a screen should change, give the parent achildrenarray and add a nested outlet to the parent’s template.export const routes: Routes = [ { path: 'products', component: ProductsComponent, children: [ { path: ':id', component: ProductDetailComponent } ] } ]; - Decide how routes load and who can enter them. Lazy-load noncritical routes to shrink the initial bundle, and use guards to control client-side navigation. Both decisions are covered in the sections below.
How Angular chooses a route
Angular uses a first-match strategy. It checks the routes in the order you list them and stops at the first one whose path fits the URL. A broad pattern placed early can therefore hide a more specific route that comes after it. Put specific paths such as user/new before parameterized ones such as user/:id, and keep the ** wildcard last so it catches only paths nothing else matched. The Define routes guide documents this ordering rule.
Free tools Windows power users keep installed
One-click scans. No signup required.
Path parameters and query parameters
Path parameters are part of the route definition. In user/:id, the segment is required for that route to match. Query parameters, the values after ? such as ?page=2, are separate URL state and are not declared in the route path. Read both through ActivatedRoute, which also exposes data attached to the route. Mixing them up is a common reason a value appears to be missing: a value meant as a path parameter that was written as a query string will not match :id.
#1 Best Overall
Nested routes need an outlet in the parent
A child route only renders if its parent route is configured with children and the parent component contains a <router-outlet />. Without that nested outlet, the router has no placeholder to render the child view into, and the parent screen appears without the intended content.
Lazy loading: when to split a route out
A route can load its component on demand with loadComponent, which dynamically imports a standalone component when the route becomes active. This reduces the JavaScript included in the initial bundle, but each lazily loaded route adds a request the first time a user reaches it. Angular’s guidance is to consider eager loading for primary landing pages and lazy loading for other pages, while accounting for the cost of nested lazy-loading layers and your application’s performance needs. The official guidance at v20.angular.dev/guide/routing/define-routes gives this as general direction and does not set a universal size or timing threshold.
Rank #2
{
path: 'reports',
loadComponent: () => import('./reports/reports.component').then(m => m.ReportsComponent)
}
A practical way to decide is to keep the home page and the first screen a visitor sees in the main bundle, and lazy-load secondary areas such as admin tools, reports, or rarely visited settings pages. Check the build output and the network waterfall after the change to confirm the split is doing what you expected.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Guards: controlling navigation and its limits
Angular’s route guards run during navigation. The documented types are:
Rank #3
CanActivate, which decides whether a route can be entered.CanActivateChild, which applies the same check to a route’s child routes.CanDeactivate, which decides whether the user can leave a route, for example when a form has unsaved changes.CanMatch, which decides whether a route definition is used at all.
A guard can return a boolean, a UrlTree or RedirectCommand to send the user elsewhere, or an observable or promise that resolves to one of those. CanMatch behaves differently from the others: when it returns false, the router moves on and tries other matching routes. That makes it useful for conditional alternatives, such as serving a different component for a feature flag.
Guards are a navigation feature, not a security boundary. Angular’s route guard documentation at angular.dev/guide/routing/route-guards states it directly:
Rank #4
Never rely on client-side guards as the sole source of access control.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchSpecial offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
The guide explains the reason: code running in the browser can be modified by the user, so a guard can always be bypassed on the client. Authorization must be enforced on the server, where each API request is checked against the user’s permissions.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting checklist
- A route never matches. Check whether a broader path or
**appears earlier in the array. Move the specific route above it. - A child view is blank. Confirm the parent route has a
childrenarray and that the parent’s template includes<router-outlet />. - Clicking a link reloads the page. Confirm the anchor uses
routerLinkrather than a plainhref, and thatRouterLinkis listed in the component’simports. - A route parameter is undefined. Confirm the path declares the segment with a colon, such as
:id, and that the link supplies it in the path rather than the query string. - A lazy route fails to load. Check the import path in
loadComponentand that the target is a standalone component.
Next steps
Start with the three-file setup: routes, the application configuration, and a root template with an outlet. Once navigation works, add nested and lazy routes one at a time so that any route-order or outlet problem is easy to isolate.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

