How to Router in Angular: A Practical Guide

Learn how to set up and optimize routing in Angular with a practical, step-by-step guide. Cover basic routes, lazy loading, guards, and navigation using clear code examples.

WiFi Router Help
WiFi Router Help Team
·5 min read
Quick AnswerSteps

To implement routing in Angular, define routes in a dedicated module, import RouterModule.forRoot(routes), and use routerLink and <router-outlet> in templates. Add lazy loading for feature modules, guard routes with canActivate, and handle route parameters with ActivatedRoute. This guide shows practical, copy-ready examples to get you started.

Basic router setup in Angular\n\nA minimal Angular router setup requires an AppRoutingModule that imports RouterModule.forRoot with the routes array. This module is then imported into AppModule to enable router infrastructure across the app. The routing module keeps all path-to-component mappings centralized and promotes reuse as the app grows.\n\ntypescript\nimport { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\nimport { HomeComponent } from './home/home.component';\nimport { AboutComponent } from './about/about.component';\n\nconst routes: Routes = [\n { path: '', component: HomeComponent },\n { path: 'about', component: AboutComponent }\n];\n\n@NgModule({\n imports: [RouterModule.forRoot(routes)],\n exports: [RouterModule]\n})\nexport class AppRoutingModule { }\n\n\nThis module is the central point for your app-wide navigation. You can extend it with child modules and additional guards as your requirements grow.

Lazy loading and nested routes\n\nLazy loading defers loading a module until its route is visited. This reduces the initial bundle size and improves startup time for large apps. Nested routes enable a single layout to serve multiple child views.\n\ntypescript\n// app-routing.module.ts\nconst routes: Routes = [\n { path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) },\n { path: 'dashboard', component: DashboardComponent }\n];\n,typescript\n// admin-routing.module.ts inside AdminModule\nconst adminRoutes: Routes = [\n { path: '', component: AdminHomeComponent },\n { path: 'settings', component: AdminSettingsComponent }\n];\n\n\nNested routes under admin allow AdminModule to provide its own RouterOutlet for admin features. You must declare AdminModule and AdminRoutingModule appropriately.

Guards and access control on routes\n\nRoute guards enforce authentication or other checks before navigation. A guard can prevent access to a route, redirect to login, or load alternate content. Implement a simple AuthGuard to illustrate the pattern.\n\ntypescript\nimport { Injectable } from '@angular/core';\nimport { CanActivate, Router } from '@angular/router';\nimport { AuthService } from './auth.service';\n\n@Injectable({ providedIn: 'root' })\nexport class AuthGuard implements CanActivate {\n constructor(private auth: AuthService, private router: Router) {}\n canActivate(): boolean {\n if (this.auth.isLoggedIn()) return true;\n this.router.navigate(['/login']);\n return false;\n }\n}\n\n\nApply the guard to routes to restrict access. You can create more guards for roles, data validation, or feature flags.

Advanced topics: resolvers and preloading\n\nResolvers fetch data before a route activates, ensuring the component has data as soon as it loads. Preloading strategies can further optimize navigation by loading modules in the background after the initial load.\n\ntypescript\n// app-routing.module.ts with preloading\nimports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],\n\n\ntypescript\n// user-resolver.ts\nimport { Injectable } from '@angular/core';\nimport { Resolve, ActivatedRouteSnapshot } from '@angular/router';\nimport { Observable } from 'rxjs';\nimport { User } from './user.model';\nimport { UserService } from './user.service';\n\n@Injectable({ providedIn: 'root' })\nexport class UserResolver implements Resolve<User> {\n constructor(private service: UserService) {}\n resolve(route: ActivatedRouteSnapshot): Observable<User> {\n const id = route.paramMap.get('id')!;\n return this.service.getUser(id);\n }\n}\n\n\ntypescript\n// profile route using resolver\n{ path: 'profile/:id', component: ProfileComponent, resolve: { user: UserResolver } }\n\n\nResolvers and preloading help deliver data efficiently while keeping the app responsive.

Troubleshooting common issues\n\nEven with clear route definitions, issues can arise from misconfigured modules or path conflicts. A common problem is an empty route or duplicate paths, which can lead to unexpected redirects or 404s. The first step is to review the module tree and ensure all modules are imported in the correct order.\n\nts\n// Example misleading route that could cause issues if misordered\nconst routes: Routes = [\n { path: '', redirectTo: '/home', pathMatch: 'full' },\n { path: 'home', component: HomeComponent }\n];\n\n\nNext, verify you have a dedicated AppRoutingModule and that your AppModule imports it. Finally, run a local server and test each route with the browser dev tools to observe navigation and data loading in real time.

Steps

Estimated time: 2-4 hours

  1. 1

    Scaffold project with routing

    Create a new Angular project with routing enabled to get started quickly. This sets up the initial project structure and app-routing module.

    Tip: Keep a clean module separation to simplify later lazy loading.
  2. 2

    Define the root routes

    Create a Routes array that maps paths to components and register it with RouterModule.forRoot in AppRoutingModule.

    Tip: Prefer explicit paths over wildcards during initial setup.
  3. 3

    Wire up templates

    Add routerLink directives in templates and place a <router-outlet> where the routed views should render.

    Tip: Use routerLinkActive to reflect active routes in UI.
  4. 4

    Add parameters

    Implement dynamic routes with parameters and read them via ActivatedRoute in the target component.

    Tip: Validate parameters to avoid runtime errors.
  5. 5

    Introduce lazy loading

    Convert feature modules into lazy-loaded routes to reduce initial bundle size.

    Tip: Monitor bundle sizes and use dynamic imports for modern builds.
  6. 6

    Protect routes with guards

    Create an AuthGuard or similar to restrict access based on authentication or roles.

    Tip: Return false or redirect to login when unauthorized.
Pro Tip: Use lazy loading for feature modules to improve initial load time.
Warning: Avoid deep route trees; flat, well-named paths improve UX and maintainability.
Note: Consider a resolver for data-dependent routes to ensure data is ready on load.

Prerequisites

Required

  • Required
  • npm 6+ (or Yarn)
    Required
  • Angular CLI 12+ (for routing scaffolding)
    Required
  • Basic TypeScript knowledge
    Required
  • Familiarity with HTML templates and components
    Required

Commands

ActionCommand
Create a new Angular project with routingIf you skip --routing, you can add app-routing laternpx ng new my-app --routing --style=css
Add a lazy-loaded module routeGenerates module and route configurationng generate module admins --route admins --module app-routing
Serve the app locallyOpen http://localhost:4200ng serve
Build for productionProduces a production-ready bundleng build --prod

People Also Ask

What is RouterModule.forRoot vs forChild?

RouterModule.forRoot configures the main app routes, while forChild configures routes for feature modules. Use forChild when you lazy-load a module and define its internal routes.

Root handles the main routes; Child handles module-specific routes.

How do I pass parameters in routes?

Define routes with parameters like path: 'user/:id' and read them in the component using ActivatedRoute to access route.paramMap or route.snapshot.paramMap.

Use route parameters to fetch specific data like user IDs.

How can I implement lazy loading in Angular routing?

Use loadChildren with a dynamic import to load a module only when its route is accessed. This reduces the initial bundle size and speeds up start.

Lazy loading keeps the app fast by loading features on demand.

What are route guards and why use them?

Guards control navigation, enforcing auth or permissions before activating a route. They improve security and user experience by preventing unauthorized access.

Guards keep certain pages private until the user is authorized.

How do I test routing in Angular?

Test routing with unit tests for guard logic and integration tests for navigation. Use Angular testing utilities and, where possible, end-to-end tests to verify real user flows.

Test routing like any other feature to ensure correctness.

What to Remember

  • Define Routes with a dedicated array
  • Register routes via RouterModule.forRoot
  • Use routerLink and router-outlet in templates
  • Leverage lazy loading for performance
  • Guard routes for security and UX

Related Articles