Question

How to Determine the Active Route in Angular

typescriptjavascriptangularangular2-routing

Question

In an Angular application, how can you determine which route is currently active?

For example, when building navigation with Bootstrap, you may want to mark a link or button as active when its related component is displayed inside a router-outlet.

A simple click-based solution is not enough, because the same route might be reached from multiple places in the app, such as:

  • a main navigation bar
  • a local menu inside a feature component

So the goal is to detect the active route from Angular's router state itself, rather than manually tracking which button was clicked.

What is the recommended Angular approach for this?

Short Answer

By the end of this page, you will understand how Angular identifies the current route, how to highlight active navigation links with routerLinkActive, and when to use Router or ActivatedRoute for route-aware logic in components.

Concept

Angular keeps track of navigation through its Router. Whenever the URL changes, Angular matches that URL to a configured route and renders the corresponding component inside a router-outlet.

To determine the active route, Angular gives you a few tools:

  • routerLinkActive for adding CSS classes to active links in templates
  • Router for checking the current URL in component code
  • ActivatedRoute for reading route-specific information such as params, query params, and child routes

For navigation styling, the simplest and most Angular-friendly solution is usually routerLinkActive.

Why this matters:

  • You often need to highlight the current page in a navbar.
  • You may want to show or hide UI based on the current route.
  • You may need route-aware logic for breadcrumbs, tabs, guards, or layouts.

Instead of manually tracking clicks, Angular lets you derive the active route from the router state. This is more reliable because it works for:

  • direct URL entry
  • browser back/forward navigation
  • programmatic navigation
  • multiple links pointing to the same route

Mental Model

Think of Angular Router as a GPS for your app.

  • The URL is the destination.
  • The route configuration is the map.
  • The router-outlet is the screen where the selected destination is shown.
  • routerLinkActive is like a light on the dashboard that turns on when you are currently on that route.

If you tried to track active links only by button clicks, it would be like guessing where the car is based only on which button the driver pressed earlier. That breaks as soon as the user refreshes the page, uses the browser history, or lands directly on a URL.

The router state is the source of truth.

Take Quiz

Syntax and Examples

For most navigation menus, use routerLink together with routerLinkActive.

<nav>
  <a routerLink="/home" routerLinkActive="active">Home</a>
  <a routerLink="/about" routerLinkActive="active">About</a>
  <a routerLink="/contact" routerLinkActive="active">Contact</a>
</nav>

When the current URL matches /about, Angular adds the active CSS class to that link.

Exact matching

Sometimes a parent route should only be active for the exact path.

<a
  routerLink="/home"
  routerLinkActive="active"
  [routerLinkActiveOptions]="{ exact: true }"
>
  Home
</a>

Without exact matching, /home/details may also mark /home as active.

Bootstrap-style navigation

<ul class="nav nav-pills">
  <li class="nav-item">
    <a
      class="nav-link"
      routerLink="/dashboard"
      routerLinkActive="active"
      [routerLinkActiveOptions]="{ exact: true }"
    >
      Dashboard
    </a>
  </li>
  <li class="nav-item">
    <a
      class="nav-link"
      routerLink="/reports"
      routerLinkActive="active"
    >
      Reports
    </a>
  </li>
</ul>

Checking the current route in TypeScript

If you need route logic in code instead of template styling:

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html'
})
export class NavComponent {
  constructor(public router: Router) {}

  isUsersPage(): boolean {
    return this.router.url === '/users';
  }
}

This is useful when you need conditions in component code, but for styling links, routerLinkActive is cleaner.

Step by Step Execution

Consider this template:

<a routerLink="/profile" routerLinkActive="active">Profile</a>
<router-outlet></router-outlet>

And suppose the user navigates to /profile.

What happens step by step

  1. The browser URL becomes /profile.
  2. Angular Router checks the route configuration.
  3. It finds the route mapped to /profile.
  4. Angular renders that route's component inside router-outlet.
  5. Angular evaluates directives attached to template elements.
  6. routerLinkActive sees that the current route matches /profile.
  7. Angular adds the active CSS class to the <a> element.

The rendered HTML will behave as if it were:

<a class="active">Profile</a>

If the user navigates away to /settings:

  1. Router updates the active route.
  2. routerLinkActive re-checks the match.
  3. The link no longer matches.
  4. Angular removes the active class.

Small code trace

<a routerLink="/users" routerLinkActive="active">Users</a>
<a routerLink="/settings" routerLinkActive="active">Settings</a>
  • Current URL = /users → Users gets active
  • Current URL = /settings → Settings gets active
  • Current URL = /users/42
    • Users may still be active if exact matching is not enabled

Real World Use Cases

Determining the active route is common in real Angular apps.

Navigation bars

Highlight the current page in a top navbar or sidebar.

Tabs inside a feature page

A settings screen may have routes like:

  • /settings/profile
  • /settings/security
  • /settings/billing

Each tab can use routerLinkActive to show which section is open.

Breadcrumbs and page context

Components may inspect the current route to generate labels such as:

  • Home / Products / Details
  • Admin / Users / Edit

Conditional layouts

You might hide navigation or switch layout behavior on routes like:

  • /login
  • /checkout
  • /admin

Analytics and logging

Developers often listen to route changes to track page views or user flow.

Access control UI

You may disable or hide buttons depending on the current route and route data.

Take Quiz

Real Codebase Usage

In real Angular projects, developers usually use different router tools for different jobs.

1. Use routerLinkActive for styling links

This is the standard template-level approach.

<a routerLink="/projects" routerLinkActive="active">Projects</a>

2. Use exact matching for root or parent links

<a
  routerLink="/"
  routerLinkActive="active"
  [routerLinkActiveOptions]="{ exact: true }"
>
  Home
</a>

3. Use Router.url for simple checks in component code

if (this.router.url.startsWith('/admin')) {
  // show admin-specific UI
}

4. Use router events for reacting to navigation changes

import { Component, OnInit } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs/operators';

@Component({
  selector: 'app-shell',
  template: ''
})
export class ShellComponent implements OnInit {
  currentUrl = '';

  constructor(private router: Router) {}

  ngOnInit(): void {
    this.currentUrl = this.router.url;

    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe(() => {
        this.currentUrl = this.router.url;
      });
  }
}

This pattern is common for:

  • page titles
  • analytics
  • breadcrumbs
  • layout changes

5. Use ActivatedRoute for route data, params, and nesting

import { ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

This is not mainly for styling links, but for reading information about the currently activated route.

Common patterns in codebases

  • Guard clauses: check route and return early
  • Validation: confirm route params exist before loading data
  • Configuration-based navigation: build menus from route definitions
  • Nested route awareness: detect parent and child route states

Common Mistakes

1. Tracking active state manually with click handlers

This often breaks when users refresh the page, use the browser back button, or navigate programmatically.

Broken approach:

activeTab = 'home';

setActive(tab: string) {
  this.activeTab = tab;
}

This tracks clicks, not the actual route.

Use the router state instead.

2. Forgetting exact matching

<a routerLink="/home" routerLinkActive="active">Home</a>

This may also be active for /home/details.

Fix:

<a
  routerLink="/home"
  routerLinkActive="active"
  [routerLinkActiveOptions]="{ exact: true }"
>
  Home
</a>

3. Using ActivatedRoute when Router is needed

Beginners sometimes try to get the full current URL from ActivatedRoute alone. ActivatedRoute is about the current route segment and route data, not the easiest way to check the whole URL.

Use:

  • routerLinkActive for template active classes
  • Router.url for current URL checks
  • ActivatedRoute for params and route metadata

4. Comparing URLs too strictly

return this.router.url === '/users';

This fails for URLs like:

  • /users/42
  • /users?page=2

Sometimes startsWith() or route matching is more appropriate.

5. Not unsubscribing in long-lived patterns

When subscribing to router events, be careful in components that may be destroyed frequently.

6. Styling the wrong element

With Bootstrap, the active class may need to be applied to the anchor tag or another specific element depending on the component structure. Check which element Bootstrap expects to receive the class.

Comparisons

ApproachBest forTemplate or CodeProsCons
routerLinkActiveHighlighting active navigation linksTemplateSimple, built-in, automaticMostly for UI state
Router.urlChecking current URL in logicCodeEasy to read, useful in componentsManual string checks can be fragile
ActivatedRouteParams, query params, route dataCodeGreat for route-specific dataNot the simplest choice for active-link styling
Manual click stateTemporary UI state onlyCodeSimple to start withNot reliable for real routing

routerLinkActive vs manual state

  • Use routerLinkActive when the UI should reflect the actual route.
  • Use manual state only for local UI interactions that are not tied to routing.

Router vs ActivatedRoute

  • Use Router when you need app-level navigation information such as the current URL.
  • Use ActivatedRoute when you need information from the active route segment, such as route params or route data.
Take Quiz

Cheat Sheet

<a routerLink="/path" routerLinkActive="active">Link</a>
<a
  routerLink="/path"
  routerLinkActive="active"
  [routerLinkActiveOptions]="{ exact: true }"
>
  Link
</a>
constructor(private router: Router) {}

isActive(): boolean {
  return this.router.url === '/path';
}
this.router.events
  .pipe(filter(event => event instanceof NavigationEnd))
  .subscribe(() => {
    console.log(this.router.url);
  });

Quick rules

  • Use routerLinkActive for active nav classes.
  • Use routerLinkActiveOptions with exact: true for exact path matching.
  • Use Router.url for simple current URL checks.
  • Use ActivatedRoute for params, query params, and route data.
  • Avoid manual click tracking for route-based active state.

Edge cases

  • Parent routes may stay active for child routes unless exact matching is enabled.
  • Query params and nested routes can affect string comparisons.
  • Bootstrap may expect the active class on a specific element.

FAQ

How do I highlight the current route in Angular?

Use routerLinkActive on the navigation link and provide the CSS class to apply, such as active.

What is the recommended way to detect an active route in Angular templates?

The recommended template-based approach is routerLinkActive.

How do I match only the exact route in Angular?

Use [routerLinkActiveOptions]="{ exact: true }".

Should I use Router or ActivatedRoute to get the current route?

Use Router for the current URL and navigation events. Use ActivatedRoute for params, route data, and nested route information.

Why is manual click tracking a bad way to detect the active route?

Because it does not reflect real router state when users refresh, use browser history, or navigate directly by URL.

Can multiple links point to the same route and still become active?

Yes. If multiple links target the active route, Angular can mark them all as active using routerLinkActive.

Does routerLinkActive work with nested routes?

Yes, but parent links may also be marked active unless you use exact matching.

Take Quiz

Mini Project

Description

Build a small Angular navigation bar that highlights the active page and shows the current URL in the component. This demonstrates both template-based active route styling and code-based route detection.

Goal

Create a navigation menu where the active link is styled automatically and the current URL is displayed after each navigation.

Requirements

  1. Create at least three routes such as Home, Products, and About.
  2. Add navigation links using routerLink.
  3. Highlight the active link using routerLinkActive.
  4. Use exact matching for the Home link.
  5. Display the current URL in a component using Router.
Take Quiz

Keep learning

Related questions

View more