A common task in our applications is to visually highlight the navigation link that corresponds to the current route.
In this recipe, you’ll learn how to implement it, from basic to advanced techniques based on your application’s needs.
routerLink directive
As a reminder if you are not familiar with the routerLink
directive, it is a
directive that allows you to navigate to a different route. In Angular, except
for navigating to an external URL, you should always use the routerLink
directive.
The routerLink is currently used in the opened file in the editor. Each link will unlock learning a new concept and how to use it.
Simple navigation
Let’s start with the simplest case: the About link.
By clicking on it, the page will navigate to the /about
route and display the content of the AboutComponent, as defined in the route file:
export const routes = [ { path: "/about", component: AboutComponent, },];
Now let’s visually highlight the About link when it is active.
routerActiveLink directive
The routerActiveLink
directive is a directive that allows you to highlight the navigation link that corresponds to the current route. It’s always used in conjunction with the routerLink
directive.
It even consumes info from the related routerLink to get its link and apply the active state if needed:
constructor(@Optional() private link?: RouterLink) { // ... }
private hasActiveLinks(): boolean { const isActiveCheckFn = this.isLinkActive(this.router); return (this.link && isActiveCheckFn(this.link)) || this.links.some(isActiveCheckFn);}
Based on this condition, the directive will apply css classes to the HTML tag it’s applied to.
this.classes.forEach((c) => { if (hasActiveLinks) { this.renderer.addClass(this.element.nativeElement, c); } else { this.renderer.removeClass(this.element.nativeElement, c); }});
The related css classes are defined by passing a value to the routerActiveLink
directive:
<a routerLink="/about" routerActiveLink="active">About</a>
You can also pass a list of classes, either as an array or a string, separated by spaces:
<a routerLink="/about" [routerActiveLink]="['active' 'active-link']">About</a><a routerLink="/about" routerActiveLink="active active-link">About</a>
Passing an array will require to use data binding, surrounding the directive with square brackets.
<a routerLink="/about" [routerActiveLink]="['active' 'active-link']">About</a>
Advanced navigation
-
Import the component into your MDX file:
import { Steps } from "@astrojs/starlight/components"; -
Wrap
<Steps>
around your ordered list items.
- astro.config.mjs
- package.json
Directorysrc
Directorycomponents
- Header.astro
- Title.astro
Directorypages/
- …
To kick things off, we have prepared a small demo lesson for you, where we’ll dive into the concept of event handling in JavaScript. Our task is to resuscitate a lifeless counter app by introducing the crucial element of interactivity: event listeners.
Let’s look at the preview on the right for a moment and try to click on the button that says counter is 0
. We’ll notice that it doesn’t work.
In the code for counter.js
, which you can find on the right, we have a setupCounter
function responsible for initializing our counter app. However, a crucial component is missing: an event listener for the button.
Event listeners are essential in web development as they enable our applications to respond to user actions. In this case, we need to listen for clicks on the button to increment the counter.
To address this, we’ll call the addEventListener
to attach a click
event listener to the button element. When a click is detected, we’ll execute a callback function that increments the counter and updates the innerHTML
accordingly.
export function setupCounter(element) { let counter = 0;
const setCounter = (count) => { counter = count; element.innerHTML = `count is ${counter}`; };
element.addEventListener("click", () => setCounter(counter + 1));
setCounter(0);}
This gives you a sneak peak of the TutorialKit experience, demonstrating what it’s capable of.
Happy writing!
- Installing dependencies
- Starting http server