Defina um título para cada rota - Angular Route Title
7 de Fev de 2022 • 9 min read
Como mudar o título da página de acordo com a rota - Angular
O título (<title>) da sua página é utilizado em vários lugares, porém todos tme um único propósito: dar uma boa ideia sobre o conteúdo abordado.
Para te dar uma ideia, pessoas com deficiência visual utilizam programas que fazem a leitura da tela. Ao focar em uma aba de um navegador, normalmente o título da página é lido e assim a pessoa pode decidir se aquele conteúdo é relevante ou não para sua pesquisa.
Uma técnica comum de navegação para usuários de tecnologias assistivas é ler o título da página a fim de deduzir o que ela contém. Isso ocorre porque navegar pela página para determinar o conteúdo dela pode ser confuso e consumir muito tempo.
fonte: https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element/title#specifications
Além disso, podemos comentar sobre a importância do seu título para os mecanismos de busca.
A figura abaixo mostra o navegador renderizando o conteúdo do <title> na aba:
O conteúdo do <title> é mostrado no título da aba do seu navegador
Agora vamos focar no mundo Angular! Se você está começando com Angular provavelmente já percebeu que existe um arquivo chamado index.html e que o <title> da sua aplicação está lá:
<title>ConsolelogTitleService</title>
Quando começamos um projeto novo não existe um arquivo ou configuração pronta para alterar o título de acordo com a rota. Por exemplo, considere uma aplicação com as seguintes rotas:
Conforme o usuário navega entre as rotas o título permanece o mesmo, veja abaixo ao lado direito (<title>Olá</title>):
O título da página não se altera conforme o usuário navega entre as rotas
Gerenciando o título com a classe Title
O Angular fornece uma classe chamada Title. Esta classe nos permite alterar o título da aplicação. Abaixo há um exemplo bem direto sobre isto:
constructor(private titleService: Title) {
this.titleService.setTitle('Olá');
Título definido através da classe Title
Sabendo que o Title nos permite trocar o título, podemos alterar o título dentro de cada componente vinculado a uma rota:
/* home.component.ts                      */
/* rota: /home                            */
this.titleService.setTitle('Home');
/* sobre.component.ts                     */
/* rota: /sobre                           */
export class SobreComponent {
this.titleService.setTitle('Sobre');
/* Contato.component.ts                   */
/* rota: /contato                         */
export class ContetoComponent {
this.titleService.setTitle('Contato');
Apesar de atingirmos o objetivo deste texto, alterar o título de acordo com a rota, podemos observar que esta estratégia irá funcionar bem para pequenas aplicações, mas conforme as rotas forem crescendo ficaria inviável essa excessiva duplicação de código.
Vamos avançar um pouco mais com o objetivo de criar a lógica acima em um único lugar - veja a seguir.
Router - identificando a rota ativa
Vamos fazer um rápido "parênteses" antes de voltarmos a falar sobre as rotas e seus títulos.
Inicialmente nossa aplicação carrega o AppComponent. Ele é o componente root que o Angular cria e insere no index.html.
Quando trabalhamos com rotas, dentro de seu template (app.component.html) encontraremos o elemento <router-outlet> que é onde os componentes são carregados de acordo com a rota ativa. A figura abaixo ilustra este cenário:
Esquema visual do router-outlet
Aqui é importante perceber que o AppComponent continua ativo independente da rota.
Quem vêm do ASP.NET pode fazer uma pequena analogia à MasterPage, mas lembre-se de que o mecanismo é totalmente diferente.
Então coisas que são comuns a toda a aplicação normalmente serão encontradas no template do AppComponent, como menu, footer, headers, etc. Lembre-se de que isto não é uma regra, como eu disse: normalmente.
Se o AppComponent é o root de nossa aplicação, significa que ele sempre está ativo independente da rota que estamos. Então independente da rota, no nosso cenário, o AppComponent está sempre lá. Sendo assim, podemos utilizar a classe Router para monitorar qual a rota que está ativa e assim determinar o valor do título:
import { filter } from 'rxjs';
constructor(router: Router, titleService: Title) {
// Filtramos apenas os eventos do tipo
// NavigationEnd que ocorre quando a
// navegação da rota é efetuada com sucesso.
// Para saber mais sobre sobre este eventos:
// https://angular.io/guide/router-reference#router-events
.subscribe((event: NavigationEnd | any) => {
console.log('URL ativa: ', event.url);
titleService.setTitle('Home');
case '/sobre':
titleService.setTitle('Sobre');
case '/contato':
titleService.setTitle('Contato');
titleService.setTitle('Olá');
O título é alterado de acordo com a rota
Perceba que nosso código funciona bem. Conseguimos adicionar um código para gerenciar os títulos dentro de um único lugar (AppComponent), porém novamente temos o problema do crescimento das rotas. Conforme a aplicação for crescendo teremos que adicionar vários case: neste switch.
Pensando em melhorar um pouco mais, vamos focar no arquivo app-routing.module.
Route.data - adicionando informações às rotas
No arquivo app-routing.module.ts onde normalmente declaramos as rotas, é possível notar que as rotas são do tipo Routes (const routes: Routes = [ /* ... */ ]). Se olharmos melhor a definição do Routes temos o seguinte:
Então cada rota que declaramos é do tipo Route e o conjunto de rotas define o Route[] que é a mesma coisa que Routes. Se novamente observarmos melhor, Route é uma interface com vários campos:
export declare interface Route {
pathMatch?: string;
matcher?: UrlMatcher;
canActivateChild?: any[];
canLoad?: any[];
* Additional developer-defined data provided to the component via
* `ActivatedRoute`. By default, no additional data is passed.
children?: Routes;
runGuardsAndResolvers?: RunGuardsAndResolvers;
Veja que há um campo opcional chamado data com a tipagem Data:
export declare type Data = {
Podemos utilizar este campo para atribuir quaisquer valores que julguemos necessário.
The data property in the third route is a place to store arbitrary data associated with this specific route. The data property is accessible within each activated route. Use it to store items such as page titles, breadcrumb text, and other read-only, static data.
fonte: https://angular.io/guide/router-reference
Por exemplo, podemos adicionar um valor de título na configuração de cada rota para posteriormente efetuar sua leitura quando a rota estiver ativa. Veja abaixo:
import { ContatoComponent } from './contato/contato.component';
import { SobreComponent } from './sobre/sobre.component';
data: { titulo: 'Home' },
path: 'contato',
component: ContatoComponent,
data: { titulo: 'Contato' },
component: SobreComponent,
data: { titulo: 'Sobre' },
Para efetuar a leitura do conteúdo que está no data podemos recorrer ao ActivatedRoute:
import { filter, map, switchMap } from 'rxjs';
titleService: Title
// Sempre que a navegação (rota) for finalizada...
// ...retornamos o activatedRoute...
.pipe(map(() => activatedRoute))
// ...e buscamos na árvore de rotas
// a rota que está ativa.
// Lembre-se: quando trabalhamos com rotas
// filhas (children) podemos ter várias
// rotas ativas ao mesmo tempo. O map
// abaixo trata este cenário.
// Pega o "data" da rota, que está lá
// no arquivo app-routing.module...
.pipe(switchMap((route) => route.data))
// Finalmente define o título
.subscribe((event) => titleService.setTitle(event['titulo']));
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quas ducimus facere
porro amet possimus fugiat totam labore a odio quae.
<a href="#" [routerLink]="['/home']">Home</a> |
<a href="#" [routerLink]="['/contato']">Contato</a> |
<a href="#" [routerLink]="['/sobre']">Sobre</a> |
<div style="border: 1px solid red; padding: 16px; margin: 16px auto">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ad, ducimus?
Agora chegamos no cenário desejado, atualizar o título de acordo com a rota ativa mantendo esta gestão em um único lugar (AppComponent):
TranslateService - tradução dos títulos
Caso esteja utilizando o TranslateService para trabalhar com vários idiomas, podemos seguir a mesma lógica, porém ao invés de adicionarmos o título no app-routing.module.ts vamos adicionar apenas a chave de tradução:
data: { titulo: 'home' },    // <-- chave de tradução
data: { titulo: 'contato' }, // <-- chave de tradução
data: { titulo: 'sobre' },   // <-- chave de tradução
"home": "Inicial",
"sobre": "Sobre",
"contato": "Contato"
"sobre": "About",
"contato": "Contact"
Quas ducimus facere porro amet possimus fugiat totam
labore a odio quae.
<button (click)="trocarIdioma('pt')">Português</button>
<button (click)="trocarIdioma('en')">Inglês</button>
Ad, ducimus?
Também é necessário modificar o AppComponent para sabermos se o usuário alterou o idioma. Sempre que alterar o idioma temos que traduzir o título:
chaveTitulo: string = '';
titleService: Title,
translate.addLangs(['pt', 'en']);
translate.use('pt');
// Sempre que a rota for alterada,
// guardamos a chave do título em uma
this.chaveTitulo = event['titulo'];
const tituloTraduzido = this.translate.instant(
this.chaveTitulo
titleService.setTitle(tituloTraduzido);
// Quando o usuário trocar de idioma
// o titulo do site deve ser atualizado
// para o idioma selecionado:
trocarIdioma(idioma: 'pt' | 'en') {
this.translate.use(idioma);
O Angular altera e traduz o título de acordo com a rota e idioma
A partir do Angular 14 a gestão do título ficará um pouco diferente. Vou deixar um link onde li sobre este assunto e em breve abordarei novamente o tema:
When building applications with Angular, one common thing you should do is have the page title update...