How Does Angular Routing Work?
What is it?
Angular Routing works by matching the browser URL with a route configuration and displaying the corresponding Angular component inside <router-outlet>.
For example:
/ → Home
/products → Products
/about → About
When the URL changes to /products, Angular Router finds the matching route and renders the Products component.
Full Simple Sample Program
home.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
standalone: true,
template: `<h2>Home Page</h2>`
})
export class Home {
}
products.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-products',
standalone: true,
template: `<h2>Products Page</h2>`
})
export class Products {
}
app.routes.ts
import { Routes } from '@angular/router';
import { Home } from './home';
import { Products } from './products';
export const routes: Routes = [
{ path: '', component: Home },
{ path: 'products', component: Products }
];
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)
]
};
app.ts
import { Component } from '@angular/core';
import { RouterLink, RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [
RouterLink,
RouterOutlet
],
template: `
<h1>My Application</h1>
<nav>
<a routerLink="/">Home</a> |
<a routerLink="/products">Products</a>
</nav>
<hr>
<router-outlet></router-outlet>
`
})
export class App {
}
main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { App } from './app/app';
import { appConfig } from './app/app.config';
bootstrapApplication(App, appConfig)
.catch(err => console.error(err));
How Does It Work?
Suppose the user clicks:
<a routerLink="/products">Products</a>
The complete flow is:
User clicks Products
↓
routerLink changes URL
↓
Browser URL becomes /products
↓
Angular Router detects URL change
↓
Router checks app.routes.ts
↓
Finds:
{ path: 'products', component: Products }
↓
Angular creates Products component
↓
Products component is rendered inside
<router-outlet>
Three important parts
1. Route configuration
{ path: 'products', component: Products }
means:
/products → Products component
2. routerLink
<a routerLink="/products">Products</a>
initiates Angular Router navigation.
3. router-outlet
<router-outlet></router-outlet>
is the placeholder where the matched component appears.
Key Points
- Angular Router watches navigation changes.
- It matches the URL against the configured
Routes. routerLinkis commonly used for navigation.router-outletdisplays the matched component.- Angular normally performs navigation without a full browser page reload.
provideRouter(routes)registers routing in a standalone application.
Interview Question
Q: How does Angular routing work?
Answer: Angular Router monitors navigation, matches the current URL against the configured routes, and renders the matching component inside <router-outlet>. Navigation can be triggered using routerLink or programmatically using the Router service.
2. How Was Routing Configured Using AppRoutingModule Before Standalone Angular?
What is it?
Before standalone APIs became the preferred approach, Angular applications commonly used NgModules.
Routing was typically placed in a separate module called:
AppRoutingModule
The common structure was:
AppModule
↓
imports
↓
AppRoutingModule
↓
RouterModule.forRoot(routes)
AppRoutingModule contained the application's route configuration and exported RouterModule so routing directives were available to the application.
Full Simple Sample Program — Old NgModule Approach
home.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
template: `<h2>Home Page</h2>`
})
export class HomeComponent {
}
products.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-products',
template: `<h2>Products Page</h2>`
})
export class ProductsComponent {
}
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
import { ProductsComponent } from './products.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'products', component: ProductsComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule {
}
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1>My Application</h1>
<nav>
<a routerLink="/">Home</a> |
<a routerLink="/products">Products</a>
</nav>
<hr>
<router-outlet></router-outlet>
`
})
export class AppComponent {
}
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HomeComponent } from './home.component';
import { ProductsComponent } from './products.component';
import { AppRoutingModule } from './app-routing.module';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
ProductsComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [
AppComponent
]
})
export class AppModule {
}
main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.error(err));
Explanation
Step 1: Create routes
Inside app-routing.module.ts:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'products', component: ProductsComponent }
];
This establishes:
/ → HomeComponent
/products → ProductsComponent
Step 2: RouterModule.forRoot(routes)
The important code was:
RouterModule.forRoot(routes)
This configured Angular's Router with the application's root route configuration.
@NgModule({
imports: [
RouterModule.forRoot(routes)
]
})
forRoot() was normally used once, for the application's root router configuration.
Step 3: Export RouterModule
exports: [
RouterModule
]
This made router directives such as:
routerLink
router-outlet
available to components belonging to modules that imported AppRoutingModule.
Step 4: Import AppRoutingModule
AppModule imported the routing module:
imports: [
BrowserModule,
AppRoutingModule
]
So the relationship was:
AppModule
│
└── imports AppRoutingModule
│
└── RouterModule.forRoot(routes)
│
└── Angular Router
Old vs Modern Routing
| Before Standalone | Modern Standalone |
|---|---|
AppModule |
No AppModule required |
AppRoutingModule commonly used |
app.routes.ts |
RouterModule.forRoot(routes) |
provideRouter(routes) |
Components declared in declarations |
Components are standalone |
bootstrapModule(AppModule) |
bootstrapApplication(App) |
RouterModule exported/imported |
RouterLink, RouterOutlet imported directly |
Old approach
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule {
}
Modern standalone approach
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes)
]
};
The routing concept has not fundamentally changed:
URL
↓
Router
↓
Route Configuration
↓
Component
↓
Router Outlet
What changed significantly is how the Router and application dependencies are configured.
Key Points
- Traditional Angular applications used
NgModule. - Routing was commonly separated into
AppRoutingModule. RouterModule.forRoot(routes)configured root-level routing.AppRoutingModulenormally exportedRouterModule.AppModuleimportedAppRoutingModule.- Components were declared in the
declarationsarray. - Modern standalone Angular typically uses:
provideRouter(routes)
instead of:
RouterModule.forRoot(routes)
Interview Questions and Answers
1. What was AppRoutingModule?
AppRoutingModule was a conventional Angular NgModule used to keep application routing configuration separate from AppModule.
2. What was RouterModule.forRoot()?
It configured Angular Router with the application's root routes.
RouterModule.forRoot(routes)
3. Why was RouterModule exported from AppRoutingModule?
It allowed routing directives such as routerLink and router-outlet to be available to components in the importing module.
4. What is the modern replacement for RouterModule.forRoot(routes)?
In standalone Angular applications, the common equivalent is:
provideRouter(routes)
5. AppRoutingModule vs app.routes.ts — what is the difference?
AppRoutingModule is an NgModule-based routing configuration, while app.routes.ts typically just exports a Routes array used with the standalone router configuration.
provideRouter(routes)
Interview-ready summary
Before standalone Angular, routing was commonly configured in an
AppRoutingModuleusingRouterModule.forRoot(routes), and that routing module was imported intoAppModule. In modern standalone Angular, routes are typically defined inapp.routes.tsand registered usingprovideRouter(routes)during application bootstrap.