I want to match for a language in my routing service. My problem is that the language needs to be first in my route.
For example:
/en/xxx
/fr/xxx
/en/yyy
/fr/yyy
Since I want to use this parameter i have added the following route
{ path: ':lang', children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}
The issue is that everything matches :lang.
For example:
/abc/xxx
I would like to add constraints to this so that I can say that :lang can only be of type <'nl' | 'fr' | 'en' | 'de'>.
Now when I want to go to /robots.txt (which should show me the robots.txt file) it maps to :lang and sends me to "/robots.txt/xxx"
I have tried mapping every language separately but then i don't have access to the route parameter.
I have tried adding the robots.txt above but since it's a assets file, i don't know how to show it by adding a line in the routes.ts file.
I have tried adding an exception in the route guard but then I can't redirect to robots.txt since it just keeps mapping on the :lang parameter.
This is my current routes.ts file:
{path: '', redirectTo: '/xxx', pathMatch: 'full', canActivate: [LangGuard]},
{path: 'xxx', component: xxx, canActivate: [LangGuard]},
{path: 'yyy', component: yyy, canActivate: [LangGuard]},
{ path: ':lang', canActivate: [LangGuard], children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}
My LangGuard is pretty extensive but ill write a short version down:
Get route parameters
If parameter is "nl", "fr", "de" or "en"
then return true //do nothing
else router.navigate('/' + decideLanguage() + state.url) // redirect to new url
Maybe a little overview of what i want to achieve and what i am getting:
What i want
/ -> /en/xxx
/abc -> /en/xxx
/xxx -> /en/xxx
/yyy -> /en/yyy
/en/xxx -> ok
/fr/xxx -> ok
/de/xxx -> ok
/en/abc -> notfound
/abc/xxx -> notfound
/abc/yyy -> notfound
/robots.txt -> ok
What I have
/ -> /en/xxx
/abc -> /en/xxx
/xxx -> /en/xxx
/yyy -> /en/yyy
/en/xxx -> ok
/fr/xxx -> ok
/de/xxx -> ok
/en/abc -> notfound
/abc/xxx -> ok (WRONG)
/abc/yyy -> ok (WRONG)
/robots.txt -> /robots.txt/xxx (WRONG)
NOTE: I can't use redirectTo for the language because the language is selected according to the localstorage, thats why i am using the routeguard
If I need to add more information or you have some questions, feel free to ask and I will answer them to the best of my abilities.
Thank you
I would give a try to Angular UrlMatcher . With that you can define your own url matching function. IMHO The guards are more meant to check authentication, not to check if the route is valid or not.
Here goes an example:
Routing
export function checkLang(url: UrlSegment[]) {
return url[0].path.startsWith('en') || url[0].path.startsWith('fr') || url[0].path.startsWith('de') || url[0].path.startsWith('nl') ? ({consumed: url}) : null;
}
export const routes = [ matcher: checkLang, component: TestComponent, children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}]
and then the TestComponent
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-test',
template: '<div>HELLO</div>'
})
export class TestComponent implements OnInit {
constructor(
public route: ActivatedRoute,
public router: Router
) { }
ngOnInit() {
console.log('LANGUAGE: ' + this.route.snapshot.url[0].path); // here you get the language and you can act consequently
}
}