I'm trying to create an app with a global nav (in AppComponent before router-outlet) and subroutes. The web app is built on the multi-tenant model with an url like this http://serveraddress/tenantSpace/:tenantUrl/ and I can't get the result I want in my routerLinks relative paths. I always get a / instead of full param path.
Here is what I tried:
So the route of each tenant will start after /tenantSpace/:tenantUrl/. So what I have for my routerLinks in my navigation is something like:
<a routerLink="./page1">Page1</a>
which I expect will give me:
<a routerLink="/tenantSpace/tenantSpace1/page1" href="/tenantSpace/tenantSpace1/page1">Page1</a>
The problem is that I always get /page1. The relative path is not evaluated even if I'm on a page at the same level as Page1 for example in /tenantSpace/tenantSpace1/page2.
If I put a routerlink inside the page1 component I get the good router.url but when the global navigation in AppComponent is evaluated the router.url is always /
So I'm sure I don't understand the way routing works in Angular and I don't find any ressources on this. If someone could help I would be very grateful.
Here is a stackblitz to illustrate the issue (you will find my route configuration inside):
Actually ./
routing means the relative position of the current route of the component; since it's in app.component
, the relative positioning is /
so Angular is working fine.
To solve your problem, you need to create a component called webspaces
, which will contain <router-outlet/>
. Inside that we will subscribe the latest value of the params webSpaceName
and store it in a service. Like so:
webspaces.com.ts
import { Component } from '@angular/core';
import { ActivatedRoute, RouterOutlet, Params } from '@angular/router';
import { WebspaceService } from '../webspace.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-webspaces',
standalone: true,
imports: [RouterOutlet],
templateUrl: './webspaces.component.html',
styleUrl: './webspaces.component.scss',
})
export class WebspacesComponent {
subscription: Subscription = new Subscription();
constructor(
private activatedRoute: ActivatedRoute,
private webspaceService: WebspaceService
) {
this.subscription.add(
this.activatedRoute.params.subscribe((params: Params) => {
this.webspaceService.webspace = params?.['webSpaceName'] || '';
})
);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
webspaces html
<router-outlet/>
In the root component when we route, we append the parameter and then perform the routing as shown below:
app html
<nav>
<a [routerLink]="['webspaces', webspace, 'properties']">Properties</a>
</nav>
<router-outlet></router-outlet>
app ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink, RouterModule, RouterOutlet } from '@angular/router';
import { WebspaceService } from './webspace.service';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, RouterOutlet, RouterModule, RouterLink],
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
title = 'AppTest';
get webspace() {
return this.webspaceService.webspace;
}
constructor(private webspaceService: WebspaceService) {}
}
stackblitz -> cd test
-> npm i
-> npm run start