Post

Conditional Routing in Angular with canMatch Guards

Introduction

Routing in Angular is essential for building feature-rich, user-friendly applications. Often, we need to conditionally load different components based on user-specific data, such as access levels, subscriptions, or even preferences. Angular’s canMatch guard provides a powerful way to control which routes are accessible by dynamically matching the route based on custom logic.

In this article, we’ll explore how to use the canMatch guard in Angular, with a practical example of showing different components based on user subscription status.

What is canMatch?

The canMatch guard in Angular allows you to dynamically control which route should be matched based on a function’s logic. Unlike canActivate, which decides whether a route can be activated, canMatch allows you to decide whether the route itself can be matched, before it’s even considered for activation.

A Real-World Example: Premium Content Access

Let’s say we are building a video streaming platform, where some content is available only to users with a premium subscription. We want to ensure that premium users access a special component showing premium content, while regular users access a different component.

Step 1: Defining the Guard

We’ll create a guard function that checks the user’s subscription status using a SubscriptionService.

1
2
3
4
5
6
export const isPremiumUserGuard = (): canMatchFn => {
  return (route, segments) => {
    const subscriptionService = inject(SubscriptionService);
    return subscriptionService.hasPremiumAccess();
  };
};

Here, we use Angular’s inject() function to access the SubscriptionService, which checks if the user has premium access.

Step 2: Configuring the Routes

Now we set up our routes, ensuring that premium users access a PremiumContentComponent and regular users access a RegularContentComponent.

1
2
3
4
5
6
7
8
9
10
11
[
  {
    path: 'content',
    canMatch: [isPremiumUserGuard()],
    loadComponent: () => import('./premium-content').then(m => m.PremiumContentComponent),
  },
  {
    path: 'content',
    loadComponent: () => import('./regular-content').then(m => m.RegularContentComponent),
  }
]

In this setup:

  • The first route will be matched if the user is a premium subscriber.
  • If the user doesn’t have premium access, the router falls back to the second route, loading the regular content.

Why Use canMatch Instead of canActivate?

You might wonder why we use canMatch rather than canActivate. The key difference is that canMatch prevents the router from even considering a route if the guard returns false, while canActivate still loads the route but decides whether or not to activate it. This makes canMatch more efficient for routes that should not even be matched in certain conditions.

Conclusion

Using the canMatch guard in Angular allows you to create dynamic and flexible routing based on user-specific data. Whether you’re managing subscription access, roles, or custom preferences, canMatch gives you the power to control which components your users see, creating a smoother and more personalized experience.

This post is licensed under CC BY 4.0 by the author.