📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados no Módulo 05: JavaScript Fundamentos e DOM. Recomendado revisar antes de iniciar a execução.
v1.0 — Arquitetura de micro-roteamento client-side com History API (pushState, popstate), ciclo de vida de views e interceptação de navegação.
Trilha de Especialização Pedagógica — Série Front-End Moderno (Projeto 3 de 10)
- Design System & Tokens
- Manipulação Avançada de DOM & Storage
- SPA Vanilla Router (este): History API, Client-Side Routing e Lifecycle
- Mini-Framework Reativo com Virtual DOM
🎓 Nível Profissional Simulado: Engenheiro Frontend Pleno. Antes da existência de React Router ou Vue Router, as Single Page Applications dependiam da manipulação direta da History API do navegador. Compreender como interceptar links
<a>, gerenciar a pilha de navegação e instanciar views sob demanda sem round-trips ao servidor é essencial para arquiteturas de alta fidelidade.
O projeto adota a convenção padronizada de subpastas por camada e tecnologia <camada>-<tecnologia>:
catalogo_projetos/js_03_spa_vanilla_router/
├── web-vanilla/ # Motor do roteador client-side
│ └── router.js # Implementação da classe Router e registro de views
├── assets/ # Galeria de diagramas vetoriais SVG autorais
└── README.md # Documentação da arquitetura de navegação
/sobre) e abrir exatamente a tela correspondente.Router deve interceptar eventos de clique globais em links com o atributo data-link, cancelando o comportamento padrão via e.preventDefault().history.pushState(state, title, url) para alterar a barra de endereços do browser sem disparo de requisição HTTP GET de página.window.onpopstate para renderizar a view correspondente ao histórico navegado./, /sobre, /contato) e rota coringa de fallback para status 404.#app deve substituir seu innerHTML de forma atômica garantindo destruição de listeners órfãos.Window.history, Document.querySelector).document.title) deve ser atualizado dinamicamente a cada transição de rota.flowchart LR
subgraph Atores
Usuario["👤 Usuário Web"]
Browser["🌐 History API"]
end
subgraph "Sistema Vanilla Router"
UC01["UC01: Clicar em Link de Navegação"]
UC02["UC02: Interceptar com pushState"]
UC03["UC03: Disparar Evento popstate"]
UC04["UC04: Renderizar View no #app"]
UC05["UC05: Exibir Fallback 404"]
end
Usuario --> UC01
UC01 --> UC02
Browser --> UC03
UC02 --> UC04
UC03 --> UC04
UC04 -.-> UC05
| ID Requisito | História de Usuário | Caso de Uso | Método no Roteador (web-vanilla) |
API do Navegador | Status |
|---|---|---|---|---|---|
| RF-VR01 | US-VR01 | UC01 | Router.initLinkInterception() |
MouseEvent.preventDefault() |
✅ Coberto |
| RF-VR02 | US-VR01 / US-VR03 | UC02 | Router.navigateTo(url) |
history.pushState() |
✅ Coberto |
| RF-VR03 | US-VR02 | UC03 | Router.handleRoute() |
window.addEventListener('popstate') |
✅ Coberto |
| RF-VR04 | US-VR04 / US-VR05 | UC04 / UC05 | Router.routes[path] |
Tabela Hash em Memória | ✅ Coberto |
| RF-VR05 | US-VR01 | UC04 | Router.view.innerHTML |
Element.innerHTML |
✅ Coberto |
ℹ️ O trecho de código que ficava aqui não correspondia ao código do projeto e foi retirado. Consulte os arquivos em
web-vanilla.
Para permitir o uso correto da History API sem bloqueios locais do protocolo file://:
cd catalogo_projetos/js_03_spa_vanilla_router
npx serve .
# ou: python -m http.server 3000
http://localhost:3000.| Checkpoint | Procedimento de Verificação | Critério de Aceite | Status |
|---|---|---|---|
| CP-01 | Clicar no link “Sobre” com o inspecionador de rede aberto. | Nenhuma requisição HTTP disparada para recarga de documento HTML. | PASS ✅ |
| CP-02 | Verificar a barra de endereços do navegador após o clique. | URL atualizada de forma limpa para http://localhost:3000/sobre. |
PASS ✅ |
| CP-03 | Clicar no botão “Voltar” (Back) do navegador. | URL retorna para / e view da página Home é renderizada via popstate. |
PASS ✅ |
| CP-04 | Digitar manualmente no navegador uma rota inexistente /rota-fantasma. |
View de Erro 404 amigável renderizada no elemento #app. |
PASS ✅ |
| CP-05 | Inspecionar document.title em cada transição de rota. |
Título da aba do navegador sincronizado com a rota ativa. | PASS ✅ |