how to change page title in angular2 router
Solution 1:
The Title
service @EricMartinez points out has a setTitle()
method - that's all you need to set the title.
In terms of doing it automatically on route changes, as of now there's no built-in way of doing this other than subscribing to Router
and calling setTitle()
in your callback:
import {RouteConfig} from 'angular2/router';
import {Title} from 'angular2/platform/browser';
@RouteConfig([
{path: '/home', component: HomeCmp, name: 'HomeCmp' }
])
class MyApp {
constructor(router:Router, title:Title) {
router.events.subscribe((event)=>{ //fires on every URL change
title.setTitle(getTitleFor(router.url));
});
}
}
That said, I emphasize as of now because the router is still under heavy development, and I expect (or at least hope) that we'll be able to do this via RouteConfig
in the final release.
EDIT:
As of the release of Angular 2 (2.0.0), a few things have changed:
- The docs for the
Title
service are now here: https://angular.io/docs/ts/latest/api/platform-browser/index/Title-class.html - The service is imported from
'@angular/platform-browser'
Solution 2:
Here's my approach which works fine, especially for nested routes:
I use a recursive helper method to grab the deepest available title after a route has changed:
@Component({
selector: 'app',
template: `
<h1>{{title | async}}</h1>
<router-outlet></router-outlet>
`
})
export class AppComponent {
constructor(private router: Router) {
this.title = this.router.events
.filter((event) => event instanceof NavigationEnd)
.map(() => this.getDeepestTitle(this.router.routerState.snapshot.root));
}
title: Observable<string>;
private getDeepestTitle(routeSnapshot: ActivatedRouteSnapshot) {
var title = routeSnapshot.data ? routeSnapshot.data['title'] : '';
if (routeSnapshot.firstChild) {
title = this.getDeepestTitle(routeSnapshot.firstChild) || title;
}
return title;
}
}
This is assuming, that you have assigned page titles within the data property of your routes, like this:
{
path: 'example',
component: ExampleComponent,
data: {
title: 'Some Page'
}
}
Solution 3:
For Angular 4+:
If you want to use route custom data to define page title for every route path, the following approach will work for the nested routes and with angular version 4+:
You can pass page title in your route definition:
{path: 'home', component: DashboardComponent, data: {title: 'Home Pag'}},
{path: 'about', component: AboutUsComponent, data: {title: 'About Us Page'}},
{path: 'contact', component: ContactUsComponent, data: {title: 'Contact Us Pag'}},
Now, most important in your upper level component (ie AppComponent
), you can globally catch the route custom data on every route change and update the page title:
import {Title} from "@angular/platform-browser";
import { filter, map } from 'rxjs/operators';
export class AppComponent implements OnInit {
constructor(
private activatedRoute: ActivatedRoute,
private router: Router,
private titleService: Title
) { }
ngOnInit() {
this.router
.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => {
let child = this.activatedRoute.firstChild;
while (child) {
if (child.firstChild) {
child = child.firstChild;
} else if (child.snapshot.data && child.snapshot.data['title']) {
return child.snapshot.data['title'];
} else {
return null;
}
}
return null;
})).subscribe( (title: any) => {
this.titleService.setTitle(title);
});
}
The above code is tested against angular verion 4+.
Solution 4:
Its really very easy to do this, you can follow therse steps to see the immediate effects:
we provide the Title service in bootstrap:
import { NgModule } from '@angular/core';
import { BrowserModule, Title } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent
],
providers: [
Title
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Then import this service in the component you want:
import { Component } from '@angular/core';
import { Title } from '@angular/platform-browser';
@Component({
selector: 'my-app',
template:
`<p>
Select a title to set on the current HTML document:
</p>
<ul>
<li><a (click)="setTitle( 'Good morning!' )">Good morning</a>.</li>
<li><a (click)="setTitle( 'Good afternoon!' )">Good afternoon</a>.</li>
<li><a (click)="setTitle( 'Good evening!' )">Good evening</a>.</li>
</ul>
`
})
export class AppComponent {
public constructor(private titleService: Title ) { }
public setTitle( newTitle: string) {
this.titleService.setTitle( newTitle );
}
}
now click on those links to see the title changing.
you can also use ng2-meta for changing page title and description as well,you can refer to this link:
https://github.com/vinaygopinath/ng2-meta