[WebComponent and RouterLocation] General Questions
Hi Vaadin team,
I have a few questions - which answers could be added to the official doc to help other beginners. My application uses the Vaadin router for client-side routing and I am trying to style the links of my nav-bar to reflect the current active view as follows:
renderLink(route: Route): TemplateResult {
// TODO: Fix that need to reupdate at each route change
// console.log(getLocation());
return html`<a
class=${location.pathname === route.path ? 'active' : ''}
@click=${() => Router.go(route.path)}
>${route.name}</a
>`;
}
The content of my router/index.ts is as follows:
import type { Route, RouterLocation } from '@vaadin/router';
import { Router } from '@vaadin/router';
import { routes } from './routes';
const router: Router = new Router();
void router.setRoutes(routes);
export const attachRouter = (outlet: HTMLElement): void => {
router.setOutlet(outlet);
};
export const getRoutes = (): Route[] => {
return router.getRoutes();
};
export const getLocation = (): RouterLocation => {
return router.location;
};
I am bumping into a few issues.
- The
RouterLocationdoes not seem to work and to get updated when browsing to a different page. See the followingconsole.logstatements. When onhttps://localhost:9808/about

- Is it recommenced to use the default
Windows locationor theVaadin RouterLocationand why?
I would be super grateful if you could help with that so that I would be able to use the same logic on my application drawer.
Best regards, Alex
EDIT: I suspect that this behaviour has something to do with the lifecycle of the Web Component. Everything got rendered once first and then do not re-updates.
Hi, please consider using urlForName helper as demonstrated in this PR: https://github.com/IBM/pwa-lit-template/pull/64
Is it recommenced to use the default Windows location or the Vaadin RouterLocation and why?
RouterLocation contains information about currently active route, params etc. So In most of cases you probably want to use it, rather than window.location(but nothing should prevent you from using both).
@web-padawan that does not answer my issue with the styling of the link for the current active view.
-
Links for non-active views look like:

-
Links for the current active view look like:

So it is all about setting the active CSS class on my link when the current route path matches the current Windows location, however it seems that Vaadin router does not update the location and therefore the comparison class=${route.path === location.pathname ? 'active' : ''} fails.
Any idea?
Hi @aress31, vaadin-router fires a vaadin-router-location-changed event when the location changes, maybe you can update the link style in an event listener? sth like
window.addEventListener(
"vaadin-router-location-changed",
updateActiveLinkStyle
);
@haijian-vaadin I think that would do the job, would you by any chance have a minimal example - maybe worth adding to the doc - on how to do it?
@aress31 you have an example here:
http://github.com/IBM/pwa-lit-template/compare/navigation
Thanks for the example @abdonrd however I can see an issue, when clicking on a new link it works fine and update the style but when browsing via the URL to a page nothing happen, there should be some logic with the location somewhere to cover this use case isn't?
Also eslint was not really happy with the code you sent and I had to deactivate a few rules, see:
firstUpdated(): void {
attachRouter(this.outlet);
window.addEventListener(
'vaadin-router-location-changed',
(event) => {
console.log(event);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const { route } = (<CustomEvent>event).detail.location;
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
this.currentRouteName = route.name;
}
);
}
Could you please advise on how to fix eslint warnings?
Also, a small side comment, but I believe that in the lit documentation states that windows event listeners should be defined in the connectedCallback lifecycle method - please correct me if wrong. Therefore, the pwa-starter-kit should be more something like:
connectedCallback(): void {
super.connectedCallback();
window.addEventListener('scroll', this.onWindowScroll);
window.addEventListener('scroll', this.routerRestoreScroll);
window.addEventListener(
'vaadin-router-location-changed',
(event) => this.updateCurrentRouteName(<CustomEvent>event)
);
}
disconnectedCallback(): void {
super.disconnectedCallback();
window.removeEventListener('scroll', this.onWindowScroll);
window.removeEventListener(
'scroll',
this.routerRestoreScroll
);
window.removeEventListener(
'vaadin-router-location-changed',
(event) => this.updateCurrentRouteName(<CustomEvent>event)
);
}
firstUpdated(): void {
attachRouter(this.outlet);
}
@aress31 mmm it works well for me; whether I change route or enter a route directly.
And about the ESLint, it depends on how you configure your rules.
And about the event listeners, it depends; in this case for the router I prefer to use the firstUpdated().
@aress31 I have the same issue when navigating manually via URL -> how did you solve your problem? Kind regards