Reputation: 7436
I want to setup a static title(i.e. <title>
) for each separate route in an Angular app. If a route doesn't contain a title it should have the default title instead. And each title should have a common suffix.
I could just use title.setTitle()
in each page component but then the title won't change to the default one if a component has no title specified. How to add a common suffix is another problem in this scenario.
Or I could use router.event.subscribe()
to manage my titles in one place but I don't know how to tell routes apart or get any data on current route.
What is the proper and clean way of managing titles in an Angular app?
Upvotes: 4
Views: 378
Reputation: 632
One way to do this, as you already mentioned in your question, is to subscribe to router.event
. Let's assume you've got some top-level component where you want to display title. You need to subscribe to router events like so:
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
...
title: string;
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
) {}
ngOnInit() {
this.router.events
.filter(event => event instanceof NavigationEnd)
.map(() => this.activatedRoute)
.map(route => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
})
.filter(route => route.outlet === 'primary')
.mergeMap(route => route.data)
.subscribe((event: NavigationEnd) => {
this.title = event['title'] || 'Default Title';
});
}
Before subscribing to router events changes we filtering them to get specific event type: NavigationEnd
in our case. After what we should map it to get current route data
param and we make a subscription.
Then you can simply specify desired titles in your routing file:
{
path: 'home',
component: HomeComponent,
data: { title: 'Home Title' },
}
Please note that implementation of subscription might be different in your case depending on what router configuration you've got. But if you're familiar with Observables
it shouldn't be complicated to get it work, the goal here is to get access to that data object you're providing in routing file.
Using this approach you should be able to manage your document.title
easily with the help of Angular's Title
service like so:
import { Title } from '@angular/platform-browser';
...
constructor(private titleService: Title) {}
...
this.titleService.setTitle('Home Title');
Upvotes: 0
Reputation: 592
You can create a service dedicated for updating the title in your header component. Simply inject the service in your header component and subscribe to a dedicated BehaviorSubject. Then you can inject this service in any component you have and use the setTitle
method from that component which will update the title in the header component. Check out the following code.
Code:
//headerTitle.service.ts
@Injectable()
export class headerTitleService {
title = new BehaviorSubject('Initial Title');
setTitle(title: string) {
this.title.next(title);
}
}
//header.component.ts
title = '';
constructor(private headerTitleService: HeaderTitleService) {}
ngOnInit() {
this.headerTitleService.title.subscribe(updatedTitle => {
this.title = updatedTitle;
});
}
//header.component.html
<h1>{{title}} - Suffix title</h1>
//about.component.ts
constructor(private headerTitleService: HeaderTitleService) {}
ngOnInit() {
this.headerTitleService.setTitle('About');
}
Upvotes: 2