1. Introduction to Angular Routing
Routing means moving from one screen to another inside a single Angular application. In normal websites, each page may be a separate HTML file. In Angular, we usually have one application, and Angular Router decides which component should be shown for each URL.
/courses to an Angular component like Courses.
/ → Home Component
/about → About Component
/courses → Courses Component
/students/101 → Student Detail Component
2. Why Routing Is Important
Without routing, an Angular app is just one screen. With routing, the app becomes a complete website or dashboard.
3. Mental Model of Routing
Routing is a matching system. The browser has a URL. Angular checks the route list.
When it finds a matching path, it displays the matching component inside router-outlet.
4. Important Routing Files
In a modern standalone Angular app, routing commonly uses these files:
src/app/
├── app.config.ts
├── app.routes.ts
├── app.html
└── pages/
├── home/
├── about/
└── courses/
| File | Purpose | Beginner Meaning |
|---|---|---|
app.routes.ts |
Stores route definitions. | URL to component map. |
app.config.ts |
Registers router providers. | Tells Angular to use routing. |
app.html |
Contains navigation and router-outlet. |
Layout shell. |
pages |
Stores route-level page components. | Home, About, Courses, Contact. |
5. Basic Routing Setup
Create Pages
ng generate component pages/home
ng generate component pages/about
ng generate component pages/courses
ng generate component pages/contact
app.routes.ts
import { Routes } from '@angular/router';
import { Home } from './pages/home/home';
import { About } from './pages/about/about';
import { Courses } from './pages/courses/courses';
import { Contact } from './pages/contact/contact';
export const routes: Routes = [
{ path: '', component: Home },
{ path: 'about', component: About },
{ path: 'courses', component: Courses },
{ path: 'contact', component: Contact }
];
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)
]
};
6. router-outlet
router-outlet is the placeholder where Angular displays the matched route component.
app.html
<header class="site-header">
<h1>Programmers Picnic Angular</h1>
</header>
<nav class="nav">
<a routerLink="/">Home</a>
<a routerLink="/about">About</a>
<a routerLink="/courses">Courses</a>
<a routerLink="/contact">Contact</a>
</nav>
<main class="page-area">
<router-outlet></router-outlet>
</main>
<footer>
angular.learnwithchampak.live
</footer>
router-outlet.
7. routerLink
In Angular, avoid normal href for internal navigation. Use routerLink.
Basic Links
<a routerLink="/">Home</a>
<a routerLink="/about">About</a>
<a routerLink="/courses">Courses</a>
Dynamic Link
<a [routerLink]="['/students', student.id]">
View Student
</a>
href for external websites. Use routerLink for internal Angular pages.
8. Active Navigation Link
routerLinkActive lets us style the current selected link.
<a
routerLink="/courses"
routerLinkActive="active-link">
Courses
</a>
CSS
.active-link {
background: #d97706;
color: white;
border-radius: 12px;
padding: 8px 12px;
}
Exact Match for Home
<a
routerLink="/"
routerLinkActive="active-link"
[routerLinkActiveOptions]="{ exact: true }">
Home
</a>
9. Route Parameters
Route parameters are used when the URL contains a changing value.
/students/101
/students/102
/students/103
Route Definition
import { Routes } from '@angular/router';
import { StudentDetail } from './pages/student-detail/student-detail';
export const routes: Routes = [
{ path: 'students/:id', component: StudentDetail }
];
Read Route Parameter with ActivatedRoute
import { Component, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-student-detail',
templateUrl: './student-detail.html'
})
export class StudentDetail {
private route = inject(ActivatedRoute);
studentId = this.route.snapshot.paramMap.get('id');
}
student-detail.html
<h2>Student Detail</h2>
<p>Student ID: {{ studentId }}</p>
10. Query Parameters
Query parameters are used for optional information like search, filter, page number, and sort order.
/courses?level=beginner
/courses?category=angular&page=2
Create Link with Query Parameters
<a
routerLink="/courses"
[queryParams]="{ level: 'beginner', page: 1 }">
Beginner Courses
</a>
Read Query Parameters
import { Component, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-courses',
templateUrl: './courses.html'
})
export class Courses {
private route = inject(ActivatedRoute);
level = this.route.snapshot.queryParamMap.get('level');
page = this.route.snapshot.queryParamMap.get('page');
}
?.
11. Redirect Routes
Redirect routes automatically send one path to another path.
Redirect Empty Path to Home
export const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: Home },
{ path: 'about', component: About }
];
Redirect Old URL to New URL
export const routes: Routes = [
{ path: 'old-courses', redirectTo: 'courses', pathMatch: 'full' },
{ path: 'courses', component: Courses }
];
pathMatch: 'full' carefully for empty path redirects.
12. Wildcard Route: 404 Page
A wildcard route catches URLs that do not match any route.
Create Not Found Page
ng generate component pages/not-found
Add Wildcard Route
import { NotFound } from './pages/not-found/not-found';
export const routes: Routes = [
{ path: '', component: Home },
{ path: 'about', component: About },
{ path: 'courses', component: Courses },
{ path: '**', component: NotFound }
];
13. Lazy Loading
Lazy loading means Angular loads a page or feature only when the user visits it. This is useful for large apps.
Lazy Load Standalone Component
export const routes: Routes = [
{
path: '',
loadComponent: () =>
import('./pages/home/home').then(m => m.Home)
},
{
path: 'courses',
loadComponent: () =>
import('./pages/courses/courses').then(m => m.Courses)
}
];
Lazy Load Feature Routes
export const routes: Routes = [
{
path: 'students',
loadChildren: () =>
import('./features/students/students.routes')
.then(m => m.STUDENTS_ROUTES)
}
];
features/students/students.routes.ts
import { Routes } from '@angular/router';
import { StudentList } from './pages/student-list/student-list';
import { StudentDetail } from './pages/student-detail/student-detail';
export const STUDENTS_ROUTES: Routes = [
{ path: '', component: StudentList },
{ path: ':id', component: StudentDetail }
];
14. Route Guards
Guards are used to protect routes. For example, only logged-in users should open the dashboard.
Generate Guard
ng generate guard core/guards/auth
Simple Auth Guard
import { CanActivateFn, Router } from '@angular/router';
import { inject } from '@angular/core';
export const authGuard: CanActivateFn = () => {
const router = inject(Router);
const token = localStorage.getItem('token');
if (token) {
return true;
}
return router.createUrlTree(['/login']);
};
Use Guard in Routes
import { authGuard } from './core/guards/auth-guard';
export const routes: Routes = [
{ path: 'login', component: Login },
{
path: 'dashboard',
component: Dashboard,
canActivate: [authGuard]
}
];
15. Route Resolvers
A resolver loads data before a route opens. This is useful when a page must have data ready before display.
Resolver Example
import { ResolveFn } from '@angular/router';
export const courseResolver: ResolveFn = () => {
return [
{ id: 1, title: 'Angular Routing' },
{ id: 2, title: 'Angular Services' }
];
};
Use Resolver in Route
export const routes: Routes = [
{
path: 'courses',
component: Courses,
resolve: {
courses: courseResolver
}
}
];
Read Resolved Data
import { Component, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-courses',
templateUrl: './courses.html'
})
export class Courses {
private route = inject(ActivatedRoute);
courses = this.route.snapshot.data['courses'];
}
16. Hash Routing for GitHub Pages
GitHub Pages is static hosting. If you refresh a deep Angular route like /courses,
GitHub Pages may not know how to serve it. The beginner-friendly fix is hash routing.
https://angular.learnwithchampak.live/#/courses
https://angular.learnwithchampak.live/#/about
https://angular.learnwithchampak.live/#/students/101
Enable Hash Routing
import { ApplicationConfig } from '@angular/core';
import { provideRouter, withHashLocation } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withHashLocation())
]
};
Deploy for Your Custom Domain
ng deploy --base-href=/
--base-href=/.
17. Recommended Routing Folder Structure
src/app/
├── app.config.ts
├── app.routes.ts
├── app.html
├── core/
│ └── guards/
│ └── auth-guard.ts
├── shared/
│ └── components/
│ ├── header/
│ └── footer/
├── pages/
│ ├── home/
│ ├── about/
│ ├── courses/
│ ├── contact/
│ └── not-found/
└── features/
└── students/
├── students.routes.ts
└── pages/
├── student-list/
└── student-detail/
pages. Put large feature areas in features.
18. Expert Routing Patterns
Nested Routes
export const routes: Routes = [
{
path: 'dashboard',
component: DashboardLayout,
children: [
{ path: '', component: DashboardHome },
{ path: 'students', component: StudentList },
{ path: 'courses', component: CourseList }
]
}
];
Programmatic Navigation
import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.html'
})
export class Login {
private router = inject(Router);
login() {
localStorage.setItem('token', 'demo-token');
this.router.navigate(['/dashboard']);
}
}
Navigation with Replace URL
this.router.navigate(['/dashboard'], {
replaceUrl: true
});
Preloading Lazy Routes
import { ApplicationConfig } from '@angular/core';
import { provideRouter, withPreloading, PreloadAllModules } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withPreloading(PreloadAllModules))
]
};
19. Common Routing Mistakes
| Mistake | Problem | Fix |
|---|---|---|
Forgetting router-outlet |
Route changes but page component does not appear. | Add <router-outlet></router-outlet>. |
Using href for internal navigation |
Page reloads fully. | Use routerLink. |
| Wildcard route at the top | It catches all routes before real routes. | Put ** at the end. |
| Wrong base href on GitHub Pages | Blank page or broken JS/CSS. | Use --base-href=/ for your custom domain. |
| Refresh gives 404 on static hosting | Server does not know Angular route. | Use hash routing for GitHub Pages. |
| Huge routing file | Hard to maintain. | Split large features into feature route files. |
20. Student Assignment
Create a routed Angular website for Programmers Picnic.
Generate Pages
ng generate component pages/home
ng generate component pages/about
ng generate component pages/courses
ng generate component pages/contact
ng generate component pages/not-found
ng generate component pages/student-detail
Create Routes
export const routes: Routes = [
{ path: '', component: Home },
{ path: 'about', component: About },
{ path: 'courses', component: Courses },
{ path: 'contact', component: Contact },
{ path: 'students/:id', component: StudentDetail },
{ path: '**', component: NotFound }
];
Create Navigation
<nav>
<a routerLink="/" routerLinkActive="active-link" [routerLinkActiveOptions]="{ exact: true }">Home</a>
<a routerLink="/about" routerLinkActive="active-link">About</a>
<a routerLink="/courses" routerLinkActive="active-link">Courses</a>
<a routerLink="/contact" routerLinkActive="active-link">Contact</a>
</nav>
<router-outlet></router-outlet>
Deploy
ng deploy --base-href=/
Final Summary
| Question | Answer |
|---|---|
| What is routing? | Connecting URL paths to Angular components. |
| Where are routes stored? | app.routes.ts |
| What displays the matched route? | router-outlet |
| What creates internal navigation links? | routerLink |
| What catches unknown URLs? | { path: '**', component: NotFound } |
| What protects routes? | Route guards. |
| What improves large-app loading? | Lazy loading. |
| What routing style is easiest for GitHub Pages? | Hash routing with withHashLocation(). |
| What base href for angular.learnwithchampak.live? | / |