You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/br/7-bank-project/1-template-route
softchris 826e79ce56
🌐 Update translations via Co-op Translator
4 weeks ago
..
README.md 🌐 Update translations via Co-op Translator 4 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 1 month ago

README.md

Construindo um App Bancário Parte 1: Templates HTML e Rotas em um Aplicativo Web

journey
    title Your Banking App Development Journey
    section SPA Fundamentals
      Understand single-page apps: 3: Student
      Learn template concepts: 4: Student
      Master DOM manipulation: 4: Student
    section Routing Systems
      Implement client-side routing: 4: Student
      Handle browser history: 5: Student
      Create navigation systems: 5: Student
    section Professional Patterns
      Build modular architecture: 5: Student
      Apply best practices: 5: Student
      Create user experiences: 5: Student

Quando o computador de orientação da Apollo 11 navegou até a Lua em 1969, ele precisou alternar entre diferentes programas sem reiniciar todo o sistema. Aplicativos web modernos funcionam de forma semelhante eles mudam o que você vê sem recarregar tudo do zero. Isso cria a experiência fluida e responsiva que os usuários esperam hoje.

Diferentemente dos sites tradicionais que recarregam páginas inteiras a cada interação, os aplicativos web modernos atualizam apenas as partes que precisam ser alteradas. Essa abordagem, muito parecida com a forma como o controle da missão alterna entre diferentes telas enquanto mantém a comunicação constante, cria a experiência fluida que estamos acostumados.

Aqui está o que torna a diferença tão dramática:

Aplicativos Tradicionais de Múltiplas Páginas Aplicativos Modernos de Página Única
Navegação Recarregamento completo da página para cada tela
Desempenho Mais lento devido ao download completo de HTML
Experiência do Usuário Trocas bruscas de página
Compartilhamento de Dados Difícil entre páginas
Desenvolvimento Vários arquivos HTML para manter

Entendendo a evolução:

  • Aplicativos tradicionais exigem solicitações ao servidor para cada ação de navegação
  • SPAs modernos carregam uma vez e atualizam o conteúdo dinamicamente usando JavaScript
  • Expectativas dos usuários agora favorecem interações instantâneas e contínuas
  • Benefícios de desempenho incluem menor uso de banda e respostas mais rápidas

Nesta lição, vamos construir um aplicativo bancário com várias telas que fluem perfeitamente entre si. Assim como os cientistas usam instrumentos modulares que podem ser reconfigurados para diferentes experimentos, usaremos templates HTML como componentes reutilizáveis que podem ser exibidos conforme necessário.

Você trabalhará com templates HTML (modelos reutilizáveis para diferentes telas), roteamento em JavaScript (o sistema que alterna entre telas) e a API de histórico do navegador (que mantém o botão de voltar funcionando como esperado). Estas são as mesmas técnicas fundamentais usadas por frameworks como React, Vue e Angular.

Ao final, você terá um aplicativo bancário funcional que demonstra os princípios profissionais de um aplicativo de página única.

mindmap
  root((Single-Page Applications))
    Architecture
      Template System
      Client-side Routing
      State Management
      Event Handling
    Templates
      Reusable Components
      Dynamic Content
      DOM Manipulation
      Content Switching
    Routing
      URL Management
      History API
      Navigation Logic
      Browser Integration
    User Experience
      Fast Navigation
      Smooth Transitions
      Consistent State
      Modern Interactions
    Performance
      Reduced Server Requests
      Faster Page Transitions
      Efficient Resource Usage
      Better Responsiveness

Quiz Pré-Aula

Quiz pré-aula

O que Você Vai Precisar

Precisaremos de um servidor web local para testar nosso aplicativo bancário não se preocupe, é mais fácil do que parece! Se você ainda não tiver um configurado, basta instalar Node.js e executar npx lite-server na pasta do seu projeto. Este comando prático inicia um servidor local e abre automaticamente seu aplicativo no navegador.

Preparação

No seu computador, crie uma pasta chamada bank com um arquivo chamado index.html dentro dela. Vamos começar com este boilerplate HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bank App</title>
  </head>
  <body>
    <!-- This is where you'll work -->
  </body>
</html>

O que este boilerplate fornece:

  • Estabelece a estrutura do documento HTML5 com a declaração DOCTYPE adequada
  • Configura a codificação de caracteres como UTF-8 para suporte a texto internacional
  • Habilita design responsivo com a tag meta viewport para compatibilidade móvel
  • Define um título descritivo que aparece na aba do navegador
  • Cria uma seção limpa no corpo onde construiremos nosso aplicativo

📁 Prévia da Estrutura do Projeto

Ao final desta lição, seu projeto conterá:

bank/
├── index.html      <!-- Main HTML with templates -->
├── app.js          <!-- Routing and navigation logic -->
└── style.css       <!-- (Optional for future lessons) -->

Responsabilidades dos arquivos:

  • index.html: Contém todos os templates e fornece a estrutura do aplicativo
  • app.js: Gerencia roteamento, navegação e templates
  • Templates: Definem a interface para login, painel e outras telas

Templates HTML

Templates resolvem um problema fundamental no desenvolvimento web. Quando Gutenberg inventou a impressão com tipos móveis na década de 1440, ele percebeu que, em vez de esculpir páginas inteiras, poderia criar blocos de letras reutilizáveis e organizá-los conforme necessário. Templates HTML funcionam com o mesmo princípio em vez de criar arquivos HTML separados para cada tela, você define estruturas reutilizáveis que podem ser exibidas quando necessário.

flowchart TD
    A["📋 Template Definition"] --> B["💬 Hidden in DOM"]
    B --> C["🔍 JavaScript Finds Template"]
    C --> D["📋 Clone Template Content"]
    D --> E["🔗 Attach to Visible DOM"]
    E --> F["👁️ User Sees Content"]
    
    G["Login Template"] --> A
    H["Dashboard Template"] --> A
    I["Future Templates"] --> A
    
    style A fill:#e3f2fd
    style D fill:#e8f5e8
    style F fill:#fff3e0
    style B fill:#f3e5f5

Pense nos templates como projetos para diferentes partes do seu aplicativo. Assim como um arquiteto cria um projeto e o utiliza várias vezes em vez de redesenhar salas idênticas, criamos templates uma vez e os instanciamos conforme necessário. O navegador mantém esses templates ocultos até que o JavaScript os ative.

Se você quiser criar várias telas para uma página web, uma solução seria criar um arquivo HTML para cada tela que deseja exibir. No entanto, essa solução traz algumas inconveniências:

  • Você precisa recarregar todo o HTML ao alternar de tela, o que pode ser lento.
  • É difícil compartilhar dados entre as diferentes telas.

Outra abordagem é ter apenas um arquivo HTML e definir múltiplos templates HTML usando o elemento <template>. Um template é um bloco HTML reutilizável que não é exibido pelo navegador e precisa ser instanciado em tempo de execução usando JavaScript.

Vamos Construir

Vamos criar um aplicativo bancário com duas telas principais: uma página de login e um painel. Primeiro, vamos adicionar um elemento de espaço reservado ao corpo do HTML é aqui que todas as nossas diferentes telas aparecerão:

<div id="app">Loading...</div>

Entendendo este espaço reservado:

  • Cria um contêiner com o ID "app" onde todas as telas serão exibidas
  • Mostra uma mensagem de carregamento até que o JavaScript inicialize a primeira tela
  • Fornece um único ponto de montagem para nosso conteúdo dinâmico
  • Permite fácil direcionamento a partir do JavaScript usando document.getElementById()

💡 Dica Pro: Como o conteúdo deste elemento será substituído, podemos colocar uma mensagem ou indicador de carregamento que será exibido enquanto o aplicativo está carregando.

Em seguida, vamos adicionar abaixo o template HTML para a página de login. Por enquanto, colocaremos apenas um título e uma seção contendo um link que usaremos para realizar a navegação.

<template id="login">
  <h1>Bank App</h1>
  <section>
    <a href="/dashboard">Login</a>
  </section>
</template>

Desmembrando este template de login:

  • Define um template com o identificador único "login" para direcionamento no JavaScript
  • Inclui um cabeçalho principal que estabelece a marca do aplicativo
  • Contém um elemento <section> semântico para agrupar conteúdo relacionado
  • Fornece um link de navegação que levará os usuários ao painel

Depois, adicionaremos outro template HTML para a página do painel. Esta página conterá diferentes seções:

  • Um cabeçalho com um título e um link de logout
  • O saldo atual da conta bancária
  • Uma lista de transações, exibida em uma tabela
<template id="dashboard">
  <header>
    <h1>Bank App</h1>
    <a href="/login">Logout</a>
  </header>
  <section>
    Balance: 100$
  </section>
  <section>
    <h2>Transactions</h2>
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Object</th>
          <th>Amount</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </section>
</template>

Vamos entender cada parte deste painel:

  • Estrutura a página com um elemento <header> semântico contendo navegação
  • Exibe o título do aplicativo de forma consistente entre as telas para branding
  • Fornece um link de logout que leva de volta à tela de login
  • Mostra o saldo atual da conta em uma seção dedicada
  • Organiza os dados de transações usando uma tabela HTML estruturada corretamente
  • Define cabeçalhos de tabela para as colunas Data, Objeto e Valor
  • Deixa o corpo da tabela vazio para injeção de conteúdo dinâmico posteriormente

💡 Dica Pro: Ao criar templates HTML, se você quiser ver como ficará, pode comentar as linhas <template> e </template> usando <!-- -->.

🔄 Verificação Pedagógica

Entendimento do Sistema de Templates: Antes de implementar o JavaScript, certifique-se de entender:

  • Como os templates diferem dos elementos HTML regulares
  • Por que os templates permanecem ocultos até serem ativados pelo JavaScript
  • A importância da estrutura semântica do HTML nos templates
  • Como os templates permitem componentes de interface reutilizáveis

Teste Rápido: O que acontece se você remover as tags <template> ao redor do seu HTML? Resposta: O conteúdo se torna visível imediatamente e perde sua funcionalidade de template

Benefícios da Arquitetura: Templates fornecem:

  • Reutilização: Uma definição, múltiplas instâncias
  • Desempenho: Sem análise redundante de HTML
  • Manutenção: Estrutura de interface centralizada
  • Flexibilidade: Alternância dinâmica de conteúdo

Por que você acha que usamos atributos id nos templates? Poderíamos usar algo como classes?

Dando Vida aos Templates com JavaScript

Agora precisamos tornar nossos templates funcionais. Assim como uma impressora 3D transforma um projeto digital em um objeto físico, o JavaScript pega nossos templates ocultos e cria elementos visíveis e interativos que os usuários podem ver e usar.

O processo segue três etapas consistentes que formam a base do desenvolvimento web moderno. Uma vez que você entenda esse padrão, reconhecerá em muitos frameworks e bibliotecas.

Se você testar seu arquivo HTML atual em um navegador, verá que ele fica preso exibindo Loading.... Isso ocorre porque precisamos adicionar algum código JavaScript para instanciar e exibir os templates HTML.

Instanciar um template geralmente é feito em 3 etapas:

  1. Recuperar o elemento template no DOM, por exemplo, usando document.getElementById.
  2. Clonar o elemento template, usando cloneNode.
  3. Anexá-lo ao DOM sob um elemento visível, por exemplo, usando appendChild.
flowchart TD
    A[🔍 Step 1: Find Template] --> B[📋 Step 2: Clone Template]
    B --> C[🔗 Step 3: Attach to DOM]
    
    A1["document.getElementById('login')"] --> A
    B1["template.content.cloneNode(true)"] --> B  
    C1["app.appendChild(view)"] --> C
    
    C --> D[👁️ Template Visible to User]
    
    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0

Desmembrando visualmente o processo:

  • Etapa 1 localiza o template oculto na estrutura do DOM
  • Etapa 2 cria uma cópia funcional que pode ser modificada com segurança
  • Etapa 3 insere a cópia na área visível da página
  • Resultado é uma tela funcional que os usuários podem interagir

Por que precisamos clonar o template antes de anexá-lo ao DOM? O que você acha que aconteceria se pulássemos esta etapa?

Tarefa

Crie um novo arquivo chamado app.js na pasta do seu projeto e importe esse arquivo na seção <head> do seu HTML:

<script src="app.js" defer></script>

Entendendo esta importação de script:

  • Conecta o arquivo JavaScript ao documento HTML
  • Usa o atributo defer para garantir que o script seja executado após a análise do HTML
  • Permite acesso a todos os elementos do DOM, já que estão totalmente carregados antes da execução do script
  • Segue as melhores práticas modernas para carregamento de scripts e desempenho

Agora, no app.js, vamos criar uma nova função updateRoute:

function updateRoute(templateId) {
  const template = document.getElementById(templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Passo a passo, aqui está o que está acontecendo:

  • Localiza o elemento template usando seu ID único
  • Cria uma cópia profunda do conteúdo do template usando cloneNode(true)
  • Encontra o contêiner do aplicativo onde o conteúdo será exibido
  • Limpa qualquer conteúdo existente do contêiner do aplicativo
  • Insere o conteúdo do template clonado no DOM visível

Agora chame esta função com um dos templates e veja o resultado.

updateRoute('login');

O que esta chamada de função realiza:

  • Ativa o template de login passando seu ID como parâmetro
  • Demonstra como alternar programaticamente entre diferentes telas do aplicativo
  • Exibe a tela de login no lugar da mensagem "Loading..."

Qual é o propósito deste código app.innerHTML = '';? O que acontece sem ele?

Criando Rotas

Roteamento é essencialmente conectar URLs ao conteúdo correto. Considere como os operadores de telefonia antigos usavam centrais telefônicas para conectar chamadas eles recebiam uma solicitação e a direcionavam ao destino correto. O roteamento web funciona de forma semelhante, recebendo uma solicitação de URL e determinando qual conteúdo exibir.

flowchart LR
    A["🌐 URL Path<br/>/dashboard"] --> B["🗺️ Routes Object<br/>Lookup"]
    B --> C["🎯 Template ID<br/>'dashboard'"]
    C --> D["📌 Find Template<br/>getElementById"]
    D --> E["👁️ Display Screen<br/>Clone & Append"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ Not Found"]
    I --> J["🔄 Redirect to /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

Tradicionalmente, servidores web lidavam com isso servindo diferentes arquivos HTML para diferentes URLs. Como estamos construindo um aplicativo de página única, precisamos lidar com esse roteamento nós mesmos, usando JavaScript. Essa abordagem nos dá mais controle sobre a experiência do usuário e o desempenho.

flowchart LR
    A["🌐 URL Path<br/>/dashboard"] --> B["🗺️ Routes Object<br/>Lookup"]
    B --> C["🎯 Template ID<br/>'dashboard'"]
    C --> D["📄 Find Template<br/>getElementById"]
    D --> E["👁️ Display Screen<br/>Clone & Append"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ Not Found"]
    I --> J["🔄 Redirect to /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

Entendendo o fluxo de roteamento:

  • Mudanças na URL acionam uma busca na configuração de rotas
  • Rotas válidas mapeiam para IDs de templates específicos para renderização
  • Rotas inválidas acionam comportamento de fallback para evitar estados quebrados
  • Renderização de templates segue o processo de três etapas que aprendemos anteriormente

Ao falar sobre um aplicativo web, chamamos de Roteamento a intenção de mapear URLs para telas específicas que devem ser exibidas. Em um site com múltiplos arquivos HTML, isso é feito automaticamente, já que os caminhos dos arquivos são refletidos na URL. Por exemplo, com esses arquivos na sua pasta de projeto:

mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html

Se você criar um servidor web com mywebsite como raiz, o mapeamento de URL será:

https://site.com            --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/     --> mywebsite/admin/index.html

No entanto, para nosso aplicativo web, estamos usando um único arquivo HTML contendo todas as telas, então esse comportamento padrão não nos ajudará. Precisamos criar este mapa manualmente e atualizar o template exibido usando JavaScript.

Tarefa

Usaremos um objeto simples para implementar um mapa entre caminhos de URL e nossos templates. Adicione este objeto no topo do seu arquivo app.js.

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard' },
};

Entendendo esta configuração de rotas:

  • Define um mapeamento entre caminhos de URL e identificadores de templates
  • Usa sintaxe de objeto onde as chaves são caminhos de URL e os valores contêm informações de templates
  • Permite busca fácil de qual template exibir para qualquer URL dado
  • Fornece uma estrutura escalável para adicionar novas rotas no futuro Agora vamos modificar um pouco a função updateRoute. Em vez de passar diretamente o templateId como argumento, queremos obtê-lo primeiro analisando a URL atual e, em seguida, usar nosso mapa para obter o valor correspondente do ID do template. Podemos usar window.location.pathname para obter apenas a seção de caminho da URL.
function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Desmembrando o que acontece aqui:

  • Extrai o caminho atual da URL do navegador usando window.location.pathname
  • Busca a configuração de rota correspondente no nosso objeto de rotas
  • Recupera o ID do template da configuração da rota
  • Segue o mesmo processo de renderização de template de antes
  • Cria um sistema dinâmico que responde às mudanças de URL

Aqui mapeamos as rotas que declaramos para o template correspondente. Você pode testar que funciona corretamente alterando a URL manualmente no seu navegador.

O que acontece se você inserir um caminho desconhecido na URL? Como poderíamos resolver isso?

Adicionando Navegação

Com o roteamento estabelecido, os usuários precisam de uma maneira de navegar pelo aplicativo. Sites tradicionais recarregam páginas inteiras ao clicar em links, mas queremos atualizar tanto a URL quanto o conteúdo sem recarregar a página. Isso cria uma experiência mais fluida, semelhante à forma como aplicativos de desktop alternam entre diferentes visualizações.

Precisamos coordenar duas coisas: atualizar a URL do navegador para que os usuários possam salvar páginas nos favoritos e compartilhar links, e exibir o conteúdo apropriado. Quando implementado corretamente, isso cria a navegação perfeita que os usuários esperam de aplicativos modernos.

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: Clicks "Login" link
    Browser->>App: onclick event triggered
    App->>App: preventDefault() & navigate('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL updates to /dashboard
    App->>App: updateRoute() called
    App->>Template: Find & clone dashboard template
    Template->>App: Return cloned content
    App->>Browser: Replace app content with template
    Browser->>User: Display dashboard screen
    
    Note over User,Template: User clicks browser back button
    
    User->>Browser: Clicks back button
    Browser->>Browser: History moves back to /login
    Browser->>App: popstate event fired
    App->>App: updateRoute() called automatically
    App->>Template: Find & clone login template
    Template->>App: Return cloned content
    App->>Browser: Replace app content with template
    Browser->>User: Display login screen

🔄 Verificação Pedagógica

Arquitetura de Aplicação de Página Única: Verifique sua compreensão do sistema completo:

  • Como o roteamento no lado do cliente difere do roteamento tradicional no lado do servidor?
  • Por que a API de Histórico é essencial para a navegação adequada em SPAs?
  • Como os templates permitem conteúdo dinâmico sem recarregar a página?
  • Qual é o papel do tratamento de eventos na interceptação da navegação?

Integração do Sistema: Sua SPA demonstra:

  • Gerenciamento de Templates: Componentes de interface reutilizáveis com conteúdo dinâmico
  • Roteamento no Lado do Cliente: Gerenciamento de URL sem solicitações ao servidor
  • Arquitetura Orientada a Eventos: Navegação responsiva e interações do usuário
  • Integração com o Navegador: Suporte adequado para botões de histórico e avançar/voltar
  • Otimização de Desempenho: Transições rápidas e redução de carga no servidor

Padrões Profissionais: Você implementou:

  • Separação Modelo-Visualização: Templates separados da lógica da aplicação
  • Gerenciamento de Estado: Estado da URL sincronizado com o conteúdo exibido
  • Aprimoramento Progressivo: JavaScript aprimora a funcionalidade básica do HTML
  • Experiência do Usuário: Navegação fluida, semelhante a aplicativos, sem recarregar a página

<EFBFBD> Insight de Arquitetura: Componentes do Sistema de Navegação

O que você está construindo:

  • 🔄 Gerenciamento de URL: Atualiza a barra de endereço do navegador sem recarregar a página
  • 📋 Sistema de Templates: Troca de conteúdo dinamicamente com base na rota atual
  • 📚 Integração com Histórico: Mantém a funcionalidade dos botões avançar/voltar do navegador
  • 🛡️ Tratamento de Erros: Soluções elegantes para rotas inválidas ou ausentes

Como os componentes funcionam juntos:

  • Escuta eventos de navegação (cliques, mudanças no histórico)
  • Atualiza a URL usando a API de Histórico
  • Renderiza o template apropriado para a nova rota
  • Mantém uma experiência de usuário perfeita ao longo do uso

O próximo passo para nosso aplicativo é adicionar a possibilidade de navegar entre páginas sem precisar alterar a URL manualmente. Isso implica duas coisas:

  1. Atualizar a URL atual
  2. Atualizar o template exibido com base na nova URL

Já cuidamos da segunda parte com a função updateRoute, então precisamos descobrir como atualizar a URL atual.

Teremos que usar JavaScript e, mais especificamente, o history.pushState, que permite atualizar a URL e criar uma nova entrada no histórico de navegação, sem recarregar o HTML.

⚠️ Nota Importante: Embora o elemento âncora HTML <a href> possa ser usado sozinho para criar hiperlinks para diferentes URLs, ele fará o navegador recarregar o HTML por padrão. É necessário evitar esse comportamento ao lidar com roteamento personalizado em JavaScript, usando a função preventDefault() no evento de clique.

Tarefa

Vamos criar uma nova função que podemos usar para navegar em nosso aplicativo:

function navigate(path) {
  window.history.pushState({}, path, path);
  updateRoute();
}

Entendendo esta função de navegação:

  • Atualiza a URL do navegador para o novo caminho usando history.pushState
  • Adiciona uma nova entrada na pilha de histórico do navegador para suporte adequado aos botões avançar/voltar
  • Dispara a função updateRoute() para exibir o template correspondente
  • Mantém a experiência de aplicação de página única sem recarregar a página

Este método primeiro atualiza a URL atual com base no caminho fornecido e, em seguida, atualiza o template. A propriedade window.location.origin retorna a raiz da URL, permitindo reconstruir uma URL completa a partir de um caminho fornecido.

Agora que temos essa função, podemos resolver o problema que temos quando um caminho não corresponde a nenhuma rota definida. Vamos modificar a função updateRoute adicionando um fallback para uma das rotas existentes caso não consigamos encontrar uma correspondência.

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  if (!route) {
    return navigate('/login');
  }

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Pontos-chave para lembrar:

  • Verifica se existe uma rota para o caminho atual
  • Redireciona para a página de login quando uma rota inválida é acessada
  • Fornece um mecanismo de fallback que evita navegação quebrada
  • Garante que os usuários sempre vejam uma tela válida, mesmo com URLs incorretas

Se uma rota não puder ser encontrada, agora redirecionaremos para a página de login.

Agora vamos criar uma função para obter a URL quando um link é clicado e evitar o comportamento padrão de links do navegador:

function onLinkClick(event) {
  event.preventDefault();
  navigate(event.target.href);
}

Desmembrando este manipulador de clique:

  • Evita o comportamento padrão de links do navegador usando preventDefault()
  • Extrai a URL de destino do elemento de link clicado
  • Chama nossa função de navegação personalizada em vez de recarregar a página
  • Mantém a experiência fluida de aplicação de página única
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>

O que essa vinculação onclick realiza:

  • Conecta cada link ao nosso sistema de navegação personalizado
  • Passa o evento de clique para nossa função onLinkClick para processamento
  • Permite navegação fluida sem recarregar a página
  • Mantém a estrutura de URL adequada para que os usuários possam salvar nos favoritos ou compartilhar

O atributo onclick vincula o evento de click ao código JavaScript, aqui a chamada para a função navigate().

Experimente clicar nesses links, agora você deve conseguir navegar entre as diferentes telas do seu aplicativo.

O método history.pushState faz parte do padrão HTML5 e é implementado em todos os navegadores modernos. Se você estiver criando um aplicativo web para navegadores mais antigos, há um truque que você pode usar no lugar dessa API: usando um hash (#) antes do caminho, você pode implementar um roteamento que funciona com navegação de âncora regular e não recarrega a página, já que seu propósito era criar links internos dentro de uma página.

Fazendo os Botões Avançar e Voltar Funcionarem

Os botões avançar e voltar são fundamentais para a navegação na web, assim como os controladores de missão da NASA podem revisar estados anteriores do sistema durante missões espaciais. Os usuários esperam que esses botões funcionem, e quando não funcionam, isso quebra a experiência esperada de navegação.

Nossa aplicação de página única precisa de configuração adicional para suportar isso. O navegador mantém uma pilha de histórico (que temos adicionado com history.pushState), mas quando os usuários navegam por esse histórico, nosso aplicativo precisa responder atualizando o conteúdo exibido de acordo.

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: Clicks "Login" link
    Browser->>App: onclick event triggered
    App->>App: preventDefault() & navigate('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL updates to /dashboard
    App->>App: updateRoute() called
    App->>Template: Find & clone dashboard template
    Template->>App: Return cloned content
    App->>Browser: Replace app content with template
    Browser->>User: Display dashboard screen
    
    Note over User,Template: User clicks browser back button
    
    User->>Browser: Clicks back button
    Browser->>Browser: History moves back to /login
    Browser->>App: popstate event fired
    App->>App: updateRoute() called automatically
    App->>Template: Find & clone login template
    Template->>App: Return cloned content
    App->>Browser: Replace app content with template
    Browser->>User: Display login screen

Pontos principais de interação:

  • Ações do usuário disparam navegação por cliques ou botões do navegador
  • Aplicativo intercepta cliques em links para evitar recarregamento de página
  • API de Histórico gerencia mudanças de URL e pilha de histórico do navegador
  • Templates fornecem a estrutura de conteúdo para cada tela
  • Listeners de eventos garantem que o aplicativo responda a todos os tipos de navegação

Usar o history.pushState cria novas entradas no histórico de navegação do navegador. Você pode verificar isso segurando o botão voltar do seu navegador, ele deve exibir algo assim:

Captura de tela do histórico de navegação

Se você tentar clicar no botão voltar algumas vezes, verá que a URL atual muda e o histórico é atualizado, mas o mesmo template continua sendo exibido.

Isso acontece porque a aplicação não sabe que precisamos chamar updateRoute() toda vez que o histórico muda. Se você olhar a documentação de history.pushState, verá que, se o estado mudar - ou seja, se nos movermos para uma URL diferente - o evento popstate é disparado. Vamos usar isso para corrigir o problema.

Tarefa

Para garantir que o template exibido seja atualizado quando o histórico do navegador mudar, vamos anexar uma nova função que chama updateRoute(). Faremos isso no final do arquivo app.js:

window.onpopstate = () => updateRoute();
updateRoute();

Entendendo esta integração com o histórico:

  • Escuta eventos popstate que ocorrem quando os usuários navegam com os botões do navegador
  • Usa uma função arrow para uma sintaxe concisa de manipulador de eventos
  • Chama updateRoute() automaticamente sempre que o estado do histórico muda
  • Inicializa o aplicativo chamando updateRoute() quando a página é carregada pela primeira vez
  • Garante que o template correto seja exibido, independentemente de como os usuários navegam

💡 Dica Pro: Usamos uma função arrow aqui para declarar nosso manipulador de eventos popstate de forma concisa, mas uma função regular funcionaria da mesma forma.

Aqui está um vídeo de revisão sobre funções arrow:

Funções Arrow

🎥 Clique na imagem acima para assistir a um vídeo sobre funções arrow.

Agora tente usar os botões avançar e voltar do seu navegador e verifique se a rota exibida é atualizada corretamente desta vez.

O que você pode fazer nos próximos 5 minutos

  • Teste a navegação do seu aplicativo bancário usando os botões avançar/voltar do navegador
  • Experimente digitar manualmente diferentes URLs na barra de endereço para testar o roteamento
  • Abra as DevTools do navegador e inspecione como os templates são clonados no DOM
  • Experimente adicionar declarações console.log para rastrear o fluxo de roteamento

🎯 O que você pode realizar nesta hora

  • Complete o questionário pós-aula e entenda os conceitos de arquitetura SPA
  • Adicione estilos CSS para deixar os templates do seu aplicativo bancário mais profissionais
  • Implemente o desafio da página de erro 404 com tratamento de erros adequado
  • Crie o desafio da página de créditos com funcionalidade adicional de roteamento
  • Adicione estados de carregamento e transições entre trocas de templates

📅 Sua Jornada de Desenvolvimento de SPA ao Longo da Semana

  • Complete o aplicativo bancário completo com formulários, gerenciamento de dados e persistência
  • Adicione recursos avançados de roteamento, como parâmetros de rota e rotas aninhadas
  • Implemente guardas de navegação e roteamento baseado em autenticação
  • Crie componentes de template reutilizáveis e uma biblioteca de componentes
  • Adicione animações e transições para uma experiência de usuário mais suave
  • Implante sua SPA em uma plataforma de hospedagem e configure o roteamento corretamente

🌟 Sua Maestria em Arquitetura Frontend ao Longo do Mês

  • Construa SPAs complexas usando frameworks modernos como React, Vue ou Angular
  • Aprenda padrões avançados de gerenciamento de estado e bibliotecas
  • Domine ferramentas de build e fluxos de trabalho de desenvolvimento para SPAs
  • Implemente recursos de Progressive Web App e funcionalidade offline
  • Estude técnicas de otimização de desempenho para SPAs em larga escala
  • Contribua para projetos de SPA de código aberto e compartilhe seu conhecimento

🎯 Sua Linha do Tempo de Maestria em Aplicações de Página Única

timeline
    title SPA Development & Modern Web Architecture Learning Progression
    
    section Foundation (20 minutes)
        Template Systems: HTML template elements
                        : DOM manipulation
                        : Content cloning
                        : Dynamic rendering
        
    section Routing Basics (30 minutes)
        Client-side Navigation: URL management
                              : History API
                              : Route mapping
                              : Event handling
        
    section User Experience (40 minutes)
        Navigation Polish: Browser integration
                         : Back button support
                         : Error handling
                         : Smooth transitions
        
    section Architecture Patterns (50 minutes)
        Professional SPAs: Component systems
                         : State management
                         : Performance optimization
                         : Error boundaries
        
    section Advanced Techniques (1 week)
        Framework Integration: React Router
                             : Vue Router
                             : Angular Router
                             : State libraries
        
    section Production Skills (1 month)
        Enterprise Development: Build systems
                              : Testing strategies
                              : Deployment pipelines
                              : Performance monitoring

🛠️ Resumo do Kit de Ferramentas de Desenvolvimento de SPA

Após concluir esta lição, você agora domina:

  • Arquitetura de Templates: Componentes HTML reutilizáveis com renderização de conteúdo dinâmico
  • Roteamento no Lado do Cliente: Gerenciamento de URL e navegação sem recarregar a página
  • Integração com o Navegador: Uso da API de Histórico e suporte aos botões avançar/voltar
  • Sistemas Orientados a Eventos: Manipulação de navegação e gerenciamento de interações do usuário
  • Manipulação do DOM: Clonagem de templates, troca de conteúdo e gerenciamento de elementos
  • Tratamento de Erros: Soluções elegantes para rotas inválidas e conteúdo ausente
  • Padrões de Desempenho: Estratégias eficientes de carregamento e renderização de conteúdo

Aplicações no Mundo Real: Suas habilidades de desenvolvimento de SPA se aplicam diretamente a:

  • Aplicativos Web Modernos: Desenvolvimento com React, Vue, Angular e outros frameworks
  • Aplicativos Web Progressivos: Aplicativos com funcionalidade offline e experiência semelhante a apps
  • Painéis Corporativos: Aplicativos empresariais complexos com múltiplas visualizações
  • Plataformas de E-commerce: Catálogos de produtos, carrinhos de compras e fluxos de checkout
  • Gerenciamento de Conteúdo: Interfaces dinâmicas de criação e edição de conteúdo
  • Desenvolvimento Mobile: Aplicativos híbridos usando tecnologias web

Habilidades Profissionais Adquiridas: Você agora pode:

  • Arquitetar aplicações de página única com separação adequada de responsabilidades
  • Implementar sistemas de roteamento no lado do cliente que acompanhem a complexidade da aplicação
  • Depurar fluxos de navegação complexos usando ferramentas de desenvolvedor do navegador
  • Otimizar o desempenho da aplicação por meio de gerenciamento eficiente de templates
  • Projetar experiências de usuário que sejam nativas e responsivas

Conceitos de Desenvolvimento Frontend Dominados:

  • Arquitetura de Componentes: Padrões de UI reutilizáveis e sistemas de templates
  • Sincronização de Estado: Gerenciamento de estado de URL e histórico do navegador
  • Programação Orientada a Eventos: Manipulação de interações do usuário e navegação
  • Otimização de Desempenho: Manipulação eficiente do DOM e carregamento de conteúdo
  • Design de Experiência do Usuário: Transições suaves e navegação intuitiva

Próximo Nível: Você está pronto para explorar frameworks modernos de frontend, gerenciamento avançado de estado ou construir aplicações empresariais complexas!

🌟 Conquista Desbloqueada: Você construiu uma base profissional para aplicações de página única com padrões modernos de arquitetura web!


Desafio do GitHub Copilot Agent 🚀

Use o modo Agent para completar o seguinte desafio:

Descrição: Melhore o aplicativo bancário implementando tratamento de erros e um template de página 404 para rotas inválidas, aprimorando a experiência do usuário ao navegar para páginas inexistentes.

Prompt: Crie um novo template HTML com o id "not-found" que exiba uma página de erro 404 amigável com estilo. Em seguida, modifique a lógica de roteamento em JavaScript para mostrar este template quando os usuários navegarem para URLs inválidas, e adicione um botão "Ir para a Página Inicial" que redirecione para a página de login.

Saiba mais sobre o modo agent aqui.

🚀 Desafio

Adicione um novo template e rota para uma terceira página que exiba os créditos deste aplicativo.

Objetivos do desafio:

  • Criar um novo template HTML com uma estrutura de conteúdo apropriada
  • Adicionar a nova rota ao objeto de configuração de rotas
  • Incluir links de navegação para e a partir da página de créditos
  • Testar se toda a navegação funciona corretamente com o histórico do navegador

Quiz Pós-Aula

Quiz pós-aula

Revisão & Autoestudo

O roteamento é uma das partes surpreendentemente complicadas do desenvolvimento web, especialmente à medida que a web evolui de comportamentos de atualização de página para atualizações em Aplicações de Página Única. Leia um pouco sobre como o serviço Azure Static Web App lida com roteamento. Você consegue explicar por que algumas das decisões descritas nesse documento são necessárias?

Recursos adicionais de aprendizado:

  • Explore como frameworks populares como React Router e Vue Router implementam roteamento no lado do cliente
  • Pesquise as diferenças entre roteamento baseado em hash e roteamento com API de histórico
  • Aprenda sobre renderização no lado do servidor (SSR) e como ela afeta as estratégias de roteamento
  • Investigue como Aplicações Web Progressivas (PWAs) lidam com roteamento e navegação

Tarefa

Melhore o roteamento


Aviso Legal:
Este documento foi traduzido usando o serviço de tradução por IA Co-op Translator. Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional feita por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução.