In-depth Guides
Routing

Read route state

Angular Router allows you to read and use information associated with a route to create responsive and context-aware components.

Get information about the current route with ActivatedRoute

ActivatedRoute is a service from @angular/router that provides all the information associated with the current route.

      
import { Component } from '@angular/core';import { ActivatedRoute } from '@angular/router';@Component({  selector: 'app-product',})export class ProductComponent {  private activatedRoute = inject(ActivatedRoute);  constructor() {    console.log(this.activatedRoute);  }}

The ActivatedRoute can provide different information about the route. Some common properties include:

Property Details
url An Observable of the route paths, represented as an array of strings for each part of the route path.
data An Observable that contains the data object provided for the route. Also contains any resolved values from the resolve guard.
params An Observable that contains the required and optional parameters specific to the route.
queryParams An Observable that contains the query parameters available to all routes.

Check out the ActivatedRoute API docs for a complete list of what you can access with in the route.

Understanding route snapshots

Page navigations are events over time, and you can access the router state at a given time by retrieving a route snapshot.

Route snapshots contain essential information about the route, including its parameters, data, and child routes. In addition, snapshots are static and will not reflect future changes.

Here’s an example of how you’d access a route snapshot:

      
import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';@Component({ ... })export class UserProfileComponent {  readonly userId: string;  private activatedRoute = inject(ActivatedRoute);  constructor() {    // Example URL: https://www.angular.dev/users/123?role=admin&status=active#contact    // Access route parameters from snapshot    this.userId = this.route.snapshot.paramMap.get('id');    // Access multiple route elements    const snapshot = this.route.snapshot;    console.log({      url: snapshot.url,           // https://www.angular.dev      // Route parameters object: {id: '123'}      params: snapshot.params,      // Query parameters object: {role: 'admin', status: 'active'}      queryParams: snapshot.queryParams,  // Query parameters    });  }}

Check out the ActivatedRoute API docs and ActivatedRouteSnapshot API docs for a complete list of all properties you can access.

Reading parameters on a route

There are two types of parameters that developers can utilize from a route: route and query parameters.

Route Parameters

Route parameters allow you to pass data to a component through the URL. This is useful when you want to display specific content based on an identifier in the URL, like a user ID or a product ID.

You can define route parameters by prefixing the parameter name with a colon (:).

      
import { Routes } from '@angular/router';import { ProductComponent } from './product/product.component';const routes: Routes = [  { path: 'product/:id', component: ProductComponent }];

You can access parameters by subscribing to route.params.

      
import { Component, inject, signal } from '@angular/core';import { ActivatedRoute } from '@angular/router';@Component({  selector: 'app-product-detail',  template: `<h1>Product Details: {{ productId() }}</h1>`,})export class ProductDetailComponent {  productId = signal('');  private activatedRoute = inject(ActivatedRoute);  constructor() {    // Access route parameters    this.activatedRoute.params.subscribe((params) => {      this.productId.set(params['id']);    });  }}

Query Parameters

Query parameters provide a flexible way to pass optional data through URLs without affecting the route structure. Unlike route parameters, query parameters can persist across navigation events and are perfect for handling filtering, sorting, pagination, and other stateful UI elements.

      
// Single parameter structure// /products?category=electronicsrouter.navigate(['/products'], {  queryParams: { category: 'electronics' }});// Multiple parameters// /products?category=electronics&sort=price&page=1router.navigate(['/products'], {  queryParams: {    category: 'electronics',    sort: 'price',    page: 1  }});

You can access query parameters with route.queryParams.

Here is an example of a ProductListComponent that updates the query parameters that affect how it displays a list of products:

      
import { ActivatedRoute, Router } from '@angular/router';@Component({  selector: 'app-product-list',  template: `    <div>      <select (change)="updateSort($event)">        <option value="price">Price</option>        <option value="name">Name</option>      </select>      <!-- Products list -->    </div>  `})export class ProductListComponent implements OnInit {  private route = inject(ActivatedRoute);  private router = inject(Router);  constructor() {    // Access query parameters reactively    this.route.queryParams.subscribe(params => {      const sort = params['sort'] || 'price';      const page = Number(params['page']) || 1;      this.loadProducts(sort, page);    });  }  updateSort(event: Event) {    const sort = (event.target as HTMLSelectElement).value;    // Update URL with new query parameter    this.router.navigate([], {      queryParams: { sort },      queryParamsHandling: 'merge' // Preserve other query parameters    });  }}

In this example, users can use a select element to sort the product list by name or price. The associated change handler updates the URL’s query parameters, which in turn triggers a change event that can read the updated query parameters and update the product list.

For more information, check out the official docs on QueryParamsHandling.

Detect active current route with RouterLinkActive

You can use the RouterLinkActive directive to dynamically style navigation elements based on the current active route. This is common in navigation elements to inform users what the active route is.

      
<nav>  <a class="button"     routerLink="/about"     routerLinkActive="active-button"     ariaCurrentWhenActive="page">    About  </a> |  <a class="button"     routerLink="/settings"     routerLinkActive="active-button"     ariaCurrentWhenActive="page">    Settings  </a></nav>

In this example, Angular Router will apply the active-button class to the correct anchor link and ariaCurrentWhenActive to page when the URL matches the corresponding routerLink.

If you need to add multiple classes onto the element, you can use either a space-separated string or an array:

      
<!-- Space-separated string syntax --><a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a><!-- Array syntax --><a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>

When you specify a value for routerLinkActive, you are also defining the same value for ariaCurrentWhenActive. This makes sure that visually impaired users (which may not perceive the different styling being applied) can also identify the active button.

If you want to define a different value for aria, you’ll need to explicitly set the value using the ariaCurrentWhenActive directive.

Route matching strategy

By default, RouterLinkActive considers any ancestors in the route a match.

      
<a [routerLink]="['/user/jane']" routerLinkActive="active-link">  User</a><a [routerLink]="['/user/jane/role/admin']" routerLinkActive="active-link">  Role</a>

When the user visits /user/jane/role/admin, both links would have the active-link class.

Only apply RouterLinkActive on exact route matches

If you only want to apply the class on an exact match, you need to provide the routerLinkActiveOptions directive with a configuration object that contains the value exact: true.

      
<a [routerLink]="['/user/jane']"  routerLinkActive="active-link"  [routerLinkActiveOptions]="{exact: true}">  User</a><a [routerLink]="['/user/jane/role/admin']"  routerLinkActive="active-link"  [routerLinkActiveOptions]="{exact: true}">  Role</a>

If you want to be more precise in how a route is matched, it’s worth noting that exact: true is actually syntactic sugar for the full set of matching options:

      
// `exact: true` is equivalent to{  paths: 'exact',  fragment: 'ignored',  matrixParams: 'ignored',  queryParams: 'exact',}// `exact: false` is equivalent{  paths: 'subset',  fragment: 'ignored',  matrixParams: 'ignored',  queryParams: 'subset',}

For more information, check out the official docs for isActiveMatchOptions.

Apply RouterLinkActive to an ancestor

The RouterLinkActive directive can also be applied to an ancestor element in order to allow developers to style the elements as desired.

      
<div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">  <a routerLink="/user/jim">Jim</a>  <a routerLink="/user/bob">Bob</a></div>

For more information, check out the API docs for RouterLinkActive.