Identificação
- Duração: 2 horas
- Tipo: teoria aplicada e laboratório
- Entrega: aplicação Angular com múltiplas páginas
- Laboratório:
../exemplos/aula-4.5/index.html
Introdução
O que é uma URL?
URL é o endereço de um recurso na Web. Ela pode conter protocolo, domínio, caminho, parâmetros de consulta e fragmento:
https://knowledge.ai/tasks/42?tab=history#comments
└─ protocolo └ domínio └ caminho └ query └ fragmento
Nesta aula, o caminho será a parte principal. /tasks representa a lista e
/tasks/42 representa o detalhe da tarefa 42.
O que é uma rota?
Rota é uma regra que associa um padrão de URL ao componente que deve aparecer.
{ path: "tasks", component: TaskListPage }
Quando o caminho ativo é /tasks, o Router mostra TaskListPage no local definido
pela aplicação.
Rota é igual a página HTML?
Não necessariamente. Em uma aplicação Angular, várias rotas podem usar o mesmo
index.html. O Router troca componentes dentro da página carregada. Ainda assim,
cada rota deve se comportar como uma página: possuir URL, título, conteúdo principal
e navegação compreensível.
O que é uma SPA?
SPA significa single-page application, ou aplicação de página única. O navegador carrega a base da aplicação e o roteador do cliente atualiza partes da interface sem substituir todo o documento a cada clique interno.
navegação tradicional: link → servidor → novo documento HTML
navegação Angular: Router → nova URL → troca no outlet
Isso não significa que a aplicação só tenha uma tela. Ela pode ter muitas páginas lógicas, cada uma com sua URL.
O que é o Angular Router?
É a biblioteca oficial @angular/router que coordena URLs, componentes, links e
estado de navegação. Projetos criados pelo Angular CLI normalmente já incluem o
pacote.
O que é RouterOutlet?
É o espaço reservado onde o componente da rota ativa será renderizado:
<main>
<router-outlet />
</main>
O cabeçalho e a navegação ao redor permanecem. Apenas o conteúdo do outlet muda.
O que é um layout?
Layout é a estrutura persistente que organiza páginas: cabeçalho, menu, área principal e rodapé. Nesta aula, o componente raiz será o shell da Knowledge AI.
App shell
├── cabeçalho
├── navegação
└── RouterOutlet
└── página da rota ativa
routerLink é igual a href?
Ambos criam navegação em links, mas RouterLink pede ao Angular para navegar sem
recarregar todo o documento:
<a routerLink="/tasks">Tarefas</a>
Use links reais, não div com clique. Para sites externos, downloads ou recursos
que não pertencem ao Router, href continua correto.
Atualizar a página quebra uma SPA?
Pode quebrar se o servidor não estiver configurado. Ao abrir diretamente
/tasks/42, o servidor precisa entregar o index.html da aplicação para que o
Router interprete o caminho. Em produção, configuramos um fallback de rotas. Isso é
diferente da rota coringa dentro do Angular.
Como isso entra na Knowledge AI?
Criaremos um shell persistente e quatro resultados de navegação:
- dashboard em
/dashboard; - lista em
/tasks; - detalhe em
/tasks/:id; - página não encontrada para caminhos desconhecidos.
Objetivos
Ao final da aula, o aluno deverá conseguir:
- identificar partes básicas de uma URL;
- explicar rota, Router, SPA, outlet e layout;
- declarar um array
Routes; - registrar o Router com
provideRouter; - importar e usar
RouterOutlet; - navegar com
RouterLink; - indicar o link ativo de forma acessível;
- criar rotas com parâmetros;
- ler parâmetros com input binding ou
ActivatedRoute; - criar redirect inicial e rota coringa;
- explicar a ordem first match wins;
- diferenciar fallback do servidor e 404 do Angular.
Pré-requisitos
- Aulas 4.1 a 4.4 concluídas;
- componentes standalone e templates;
- inputs, serviços e injeção de dependência;
- noções de URL e requisições da Aula 1.1;
- HTML semântico e navegação por links.
Pergunta orientadora
Como transformar componentes isolados em páginas acessíveis por URLs previsíveis?
Roteiro sugerido
| Etapa | Duração |
|---|---|
| URL, rota e SPA | 20 min |
| Configuração e outlet | 25 min |
| Links, layout e acessibilidade | 25 min |
| Parâmetros, redirects e 404 | 30 min |
| Laboratório | 15 min |
| Revisão | 5 min |
1. Três peças essenciais
Routes → relacionam URL e componente
RouterOutlet → recebe o componente ativo
RouterLink → inicia navegação interna
Sem rotas, o Router não sabe o que mostrar. Sem outlet, não há destino visual. Sem links, a URL ainda pode ser digitada, mas a interface não oferece navegação.
2. Arquivo de rotas
import { Routes } from "@angular/router";
export const routes: Routes = [
{ path: "dashboard", component: DashboardPage },
{ path: "tasks", component: TaskListPage },
];
Projetos atuais costumam manter essa configuração em app.routes.ts.
3. Caminhos não começam com barra
Na configuração:
{ path: "tasks", component: TaskListPage }
No navegador, o resultado será /tasks. O Router compõe os segmentos; não coloque
/ no início de path.
4. Registrando o Router
import { ApplicationConfig } from "@angular/core";
import { provideRouter } from "@angular/router";
import { routes } from "./app.routes";
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes)],
};
provideRouter registra os serviços necessários no ambiente da aplicação.
5. Componente raiz como shell
@Component({
selector: "app-root",
imports: [RouterLink, RouterLinkActive, RouterOutlet],
templateUrl: "./app.html",
styleUrl: "./app.css",
})
export class App {}
O shell importa as diretivas que usa. As páginas roteadas não precisam ser inseridas manualmente no template raiz.
6. Criando o layout
<header>
<a routerLink="/dashboard">Knowledge AI</a>
<nav aria-label="Navegação principal">
<a routerLink="/dashboard">Dashboard</a>
<a routerLink="/tasks">Tarefas</a>
</nav>
</header>
<main id="main-content">
<router-outlet />
</main>
O header permanece enquanto o outlet troca a página.
7. Navegação declarativa
<a routerLink="/tasks">Ver tarefas</a>
Use RouterLink quando o destino faz parte da aplicação. Links preservam recursos do
navegador, como abrir em nova guia e copiar endereço.
8. Link ativo
<a
routerLink="/tasks"
routerLinkActive="is-active"
ariaCurrentWhenActive="page"
>
Tarefas
</a>
RouterLinkActive aplica a classe. ariaCurrentWhenActive="page" comunica a página
atual a tecnologias assistivas.
9. Correspondência exata
Um link para /tasks também pode ser considerado ativo em /tasks/42. Quando isso
não for desejado, configure opções de correspondência:
<a
routerLink="/tasks"
routerLinkActive="is-active"
[routerLinkActiveOptions]="{ exact: true }"
>
Decida se o item representa uma seção ou uma página específica.
10. Rotas com parâmetro
{ path: "tasks/:id", component: TaskDetailPage }
O segmento :id é variável. /tasks/7 e /tasks/42 usam o mesmo componente com
valores diferentes.
11. Criando link com parâmetro
<a [routerLink]="['/tasks', task.id]">
{{ task.title }}
</a>
O array evita concatenar manualmente segmentos e deixa a intenção clara.
12. Parâmetro não é automaticamente número
Valores da URL chegam como texto. Mesmo /tasks/42 fornece "42". Valide e
converta antes de procurar a tarefa:
const taskId = Number(id);
if (!Number.isInteger(taskId) || taskId <= 0) {
// representar identificador inválido
}
Nunca confie na URL apenas porque foi criada pela sua interface.
13. Binding de estado para inputs
Configuração atual:
providers: [
provideRouter(routes, withComponentInputBinding()),
]
Com uma rota tasks/:id, o componente pode receber o parâmetro em um input com o
mesmo nome:
export class TaskDetailPage {
readonly id = input.required<string>();
}
Essa abordagem reduz código de adaptação e mantém o contrato visível.
14. Alternativa com ActivatedRoute
export class TaskDetailPage {
private readonly route = inject(ActivatedRoute);
readonly id = this.route.snapshot.paramMap.get("id");
}
O snapshot representa um instante e não reflete mudanças futuras. Para reagir ao mesmo componente recebendo outro parâmetro, use os observables da rota ou component input binding.
15. Parâmetro de rota e query parameter
/tasks/42 → id identifica o recurso
/tasks?status=done → status ajusta filtro opcional
Use parâmetros de rota para identidade estrutural. Use query parameters para filtros, ordenação, paginação e opções que não mudam qual recurso principal é acessado.
16. Redirect inicial
{ path: "", redirectTo: "dashboard", pathMatch: "full" }
Quando a aplicação abre na raiz, o Router redireciona para /dashboard.
pathMatch: "full" é essencial no caminho vazio; sem ele, o prefixo vazio combina
com todos os caminhos e pode causar redirects indevidos.
17. Página não encontrada
{ path: "**", component: NotFoundPage }
** captura qualquer caminho ainda não reconhecido. A página deve explicar o erro e
oferecer um caminho seguro de volta.
18. A ordem importa
O Angular usa first match wins: a primeira rota compatível vence.
export const routes: Routes = [
{ path: "tasks/new", component: TaskCreatePage },
{ path: "tasks/:id", component: TaskDetailPage },
{ path: "tasks", component: TaskListPage },
{ path: "**", component: NotFoundPage },
];
Se tasks/:id viesse antes, a palavra new poderia ser tratada como identificador.
A coringa sempre fica por último.
19. Título da página
{ path: "dashboard", component: DashboardPage, title: "Dashboard | Knowledge AI" }
O Router atualiza o título do documento. Títulos específicos ajudam orientação, histórico, favoritos e acessibilidade.
20. Navegação programática
private readonly router = inject(Router);
async save(): Promise<void> {
await this.taskStore.save();
await this.router.navigate(["/tasks"]);
}
Use RouterLink para destinos declarativos. Use Router.navigate quando a navegação
depende do resultado de uma operação.
21. Rotas filhas e layouts aninhados
{
path: "settings",
component: SettingsLayout,
children: [
{ path: "profile", component: ProfilePage },
{ path: "security", component: SecurityPage },
],
}
SettingsLayout precisa de seu próprio RouterOutlet. Rotas filhas permitem manter
um layout específico enquanto apenas uma subárea muda.
22. Navegação e estado
Não guarde a página atual em um booleano como showDashboard. A URL deve ser a fonte
de verdade da navegação. Isso preserva histórico, links compartilháveis e atualização
do navegador.
23. Botões e links têm papéis diferentes
link → leva a outro endereço
botão → executa uma ação na página atual
Use <a routerLink> para abrir detalhes. Use <button> para alternar status. Não
escolha pelo estilo visual.
24. Base URL em subdiretório
Angular usa a tag <base> para resolver URLs. Na raiz do domínio:
<base href="/">
Se a compilação for publicada em /site/PosIA/app/, configure o base href para esse
subdiretório na compilação. Uma base incorreta quebra assets e navegação profunda.
25. Fallback do servidor
Ao receber /tasks/42 diretamente, Apache, Nginx ou outro host deve devolver o
index.html da aplicação quando não existir arquivo físico. Depois, o Angular decide
qual componente renderizar.
servidor: caminho sem arquivo → index.html
Angular: caminho conhecido → componente
Angular: caminho desconhecido → NotFoundPage
O fallback não deve redirecionar arquivos reais nem substituir endpoints da API.
26. Segurança
Uma rota escondida no menu não está protegida. Guards melhoram o fluxo da interface, mas autorização real precisa ser validada na API NestJS. O usuário pode digitar uma URL ou modificar o JavaScript do navegador.
27. Laboratório guiado
Abra o simulador de rotas.
Etapa 1 — Navegue pelo menu
Observe o shell permanecer enquanto o conteúdo do outlet muda.
Etapa 2 — Abra uma tarefa
A lista cria /tasks/:id; o detalhe recebe o valor do parâmetro.
Etapa 3 — Teste o histórico
Use voltar e avançar do simulador para percorrer as rotas visitadas.
Etapa 4 — Digite uma rota desconhecida
A rota ** ativa a página não encontrada sem remover o layout.
Etapa 5 — Examine a fonte
Compare configuração, shell e detalhe tipado.
28. Sobre o laboratório estático
O laboratório simula um Router dentro da página para funcionar sem instalar Angular.
A barra de endereço é didática e não altera o endereço real do material. A pasta
src/app contém a implementação Angular equivalente.
29. Erros comuns
Colocar barra no path
Use path: "tasks", não path: "/tasks".
Usar href interno e recarregar tudo
Use RouterLink para rotas pertencentes à aplicação.
Usar botão para navegação
Links comunicam destino e preservam comportamentos do navegador.
Colocar ** antes das outras rotas
A coringa captura tudo e impede as rotas seguintes.
Esquecer pathMatch: "full" no redirect vazio
O prefixo vazio combina com qualquer URL.
Tratar o parâmetro como número sem validação
Dados da URL são externos e chegam como texto.
Não configurar o servidor
Links internos funcionam, mas atualizar uma rota profunda retorna 404 do host.
Usar rota como autorização
O back-end precisa validar acesso em cada operação protegida.
30. Boas práticas
- dê URLs previsíveis às páginas;
- mantenha rotas em arquivo próprio;
- use layout semântico e um conteúdo principal;
- prefira links para navegação;
- indique a página ativa com
aria-current; - defina títulos específicos;
- ordene do mais específico ao mais genérico;
- deixe a rota coringa por último;
- valide parâmetros;
- configure base href e fallback do host;
- preserve a URL como fonte de verdade;
- não confunda navegação com autorização.
31. Exercícios
Exercício 1 — Rotas estáticas
Crie páginas /about e /settings.
Exercício 2 — Layout
Mantenha cabeçalho e navegação fora do outlet.
Exercício 3 — Parâmetro
Crie /users/:id e converta o identificador com validação.
Exercício 4 — Link ativo
Adicione classe ativa e ariaCurrentWhenActive="page".
Exercício 5 — 404
Crie uma página que explique o erro e ofereça link para o dashboard.
32. Desafio
Crie uma aplicação com:
- shell persistente;
- dashboard, lista, criação e detalhe;
provideRouter;RouterOutlet;- links acessíveis;
- títulos por rota;
- parâmetro
:idvalidado; - query parameter de filtro;
- redirect inicial com
pathMatch: "full"; - rota
**por último; - navegação programática após salvar;
- documentação do fallback necessário no servidor.
33. Lista de verificação de conclusão
- Explico URL, rota, Router e SPA.
- Sei o papel de Routes, Outlet e Link.
- Registro o Router com
provideRouter. - Construo um shell persistente.
- Uso links semânticos para navegar.
- Indico a página atual de modo acessível.
- Crio e valido parâmetro de rota.
- Diferencio route param e query param.
- Configuro redirect vazio corretamente.
- Deixo a rota coringa por último.
- Entendo base href e fallback do servidor.
34. Critérios de avaliação
| Critério | Pontos |
|---|---|
| Configuração de rotas | 20 |
| Layout e outlet | 20 |
| Links e acessibilidade | 20 |
| Parâmetros e validação | 20 |
| Redirect, 404 e ordem | 10 |
| Clareza e organização | 10 |
| Total | 100 |
Resumo
Nesta aula, aprendemos que:
- rota relaciona um padrão de URL a um componente;
- SPA pode possuir muitas páginas lógicas;
provideRouterregistra o roteador;RouterOutletmarca onde a página ativa aparece;- o layout permanece ao redor do outlet;
RouterLinknavega internamente sem recarregar o documento;- parâmetros identificam recursos e chegam como texto;
- component input binding pode entregar dados da rota a inputs;
- a primeira rota compatível vence;
- redirect vazio exige
pathMatch: "full"; **representa caminhos desconhecidos;- o servidor precisa devolver
index.htmlem rotas profundas.
Próxima aula
Na Aula 4.6, criaremos formulários tipados, validações e retorno acessível para cadastrar e editar tarefas.