Add Active & Exact Active Class to <router-link> in Vue 3

Robin
Updated on April 3, 2022

In the Vue application, we use the "Vue Router" package in order to create multiple pages. This package provides a <router-link> component to add links from one page to another.

To provide a better user experience, we need to customize these links according to the page user is visiting.

You can add custom style to those links using the default classes that the Vue Router package adds or you can add custom active and exact active classes to router-link.

Custom active class and exact active class can be added by setting "active-class" and "exact-active-class" props to the <router-link> component. To change class names for the entire application "linkActiveClass" and "linkExactActiveClass" properties can be used in the "createRouter" function.

This is the complete guide to add custom active class and exact active class to router-link in Vue 3 and how you can style your links current page in your application.

Also Read: Best Ways to Use v-model to Custom Components in Vue 3

There is a little difference between how we set up Vue Router in Vue 2 and Vue 3. But you can add your classes in the same way in both versions of Vue.

But in the case of Vue 3, you must install the latest version of Vue Router (4.0.0 or above). Older versions are not compatible with Vue 3.

By default, Vue Router adds two active classes i.e. "router-link-active" and "router-link-exact-active" to the links that we create using the "router-link" component.

You can use these classes to add styles to your links. But if you need to use different classes or you want to use short class names, you can replace these default names.

Add Custom Active & Exact Active Class to router-link in Vue 3

The Vue Router adds this class by using an inclusive match behavior. If you set /hello to the router-link as the path <router-link to="/hello">, the router-link-active class will be applied when the current page URL starts with "/hello".

If you visit two pages with the URLs /hello and /hello/world, in both cases that link will contain the "router-link-active" class. Because both URLs start with /hello.

The Vue Router adds this class when the page URL matches exactly with the path we set in the <router-link> component. This is the main difference between router-link-active and router-link-exact-active classes.

For example, if we create two links i.e.<router-link to="/hello"> and <router-link to="/hello/world">, the router-link-exact-active class will be applied to <router-link to="/hello/world"> only when the path is /hello/world.

If the path is /hello/world, both router-link-active and router-link-exact-active classes will be applied to that link.

If the path does not match exactly as you set to the router-link component, the link will not contain that class.

In Vue 2, if you have <router-link to="/">, this link will always have router-link-active class. If you don't want this default behavior, you can use exact prop <router-link to="/" exact> like this. Then this link will only have the class when path is exactly as /. But in Vue 3, you don't have to do anything. By default, it adds those classes with the exact match.

If you want to change the default class names for the entire application globally, you can do so by setting some options in the createRouter function.

You need to pass two properties to the object we pass as the createRouter function argument. These are: linkActiveClass and linkExactActiveClass.

          const router = createRouter({
    history: createWebHistory(process.env.BASE_URL),
    routes,
    linkActiveClass: 'active-link',
    linkExactActiveClass: 'exact-active-link',
});
        

I have passed the linkActiveClass property with the value "active-link". Then all the links in the application will contain the class active-link. This will replace the default router-link-active class.

The value for linkExactActiveClass property will replace the default router-link-exact-active class.

That means if the page URL is the exact match with the <router-link>, this "exact-active-link" class will be added instead of "router-link-exact-active".

Now using CSS, you can add your custom styles for the active links. This will help users to understand which page they are visiting.

          .active {
    color: #42b983;
}

.exact-active-link {
    color: #42b983;
    font-weight: bold;
}
        

Change Default Active & Exact Active Class Individually

If you want to change the default class names for individual <router-link> components not globally, you can do that by setting "active-class" and "exact-active-class" props to <router-link> components.

          <router-link active-class="active-link" exact-active-class="exact-active-link" to="/hello">Hello</router-link>
        

This link will override the default classes and add "active-link" and "exact-active-link" classes.

          <a href="/hello" class="active-link exact-active-link">Hello</a>
        

The Vue 3 will render the above <router-link> component like this in your HTML file.

Also Read: Composition API VS Options API in Vue 3 For Beginners

If you use v-slot in your <router-link> component, you can also add your custom classes. The v-slot provides 5 values that are, href, route, navigate, isActive, isExactActive.

If you want to know more about the v-slot in the <router-link> component, you can visit this official documentation.

          <router-link to="/hello" custom v-slot="{ href, navigate, isActive, isExactActive }">
    <div :class="{ 'active-link': isActive, 'exact-active-link': isExactActive }">
        <a :href="href" @click="navigate">Hello</a>
    </div>
</router-link>
        

This method is useful if you want to pass nested HTML elements to <router-link> components and want to add custom classes to the nested element instead of the actual link.

Here, isActive and isExactActive are the boolean values. The isActive value is true if the path starts with /hello. And isExactActive value is true if the path exactly matches with /hello.

The value of isActive will be true if the path contains something after it like /hello/world. The value of isExactActive will be false.

Now you can add your custom classes using these 2 boolean values. I have added "active-link" and "exact-active-link" classes conditionally.

          <div class="active-link exact-active-link">
    <a href="/hello">Hello</a>
</div>
        

The Vue 3 will render the above <router-link> component like this in your HTML file.

Conclusion

Adding custom style to the links according to the current page provides a better user experience. That's why Vue Router adds 2 classes automatically to the links based on the current page URL.

We can apply CSS styles by selecting those classes that indicate to users which page they are visiting.

In the article, I have shown how you can use those default classes and add custom active class and exact active class to router-link in Vue 3.

I hope it was helpful. Thank you so much for reading.

Related Posts