Compartilhe

API de navegação - uma maneira melhor de navegar, agora o Baseline está disponível recentemente | Blogue | web.dev

Publicado: 17 de fevereiro de 2026

Por mais de uma década, confiamos em window.history construir Aplicativos de página única (SPAs)e por mais de uma década, reclamamos disso. A razão? Nunca foi realmente projetado para SPAs. Para fornecer uma experiência perfeita, os SPAs devem imitar a navegação padrão de várias páginas, tocando manualmente no histórico do navegador para suportar os botões voltar e avançar.

O API de histórico aliviou alguns desses pontos problemáticos, mas não sem suas próprias deficiências, como ser incapaz de detectar todos os diferentes tipos de gatilhos de navegação. Outras limitações notáveis ​​incluem a incapacidade de ler a pilha completa do histórico ou editar entradas não atuais. O popstate evento também se comporta de maneira inconsistente e não é acionado quando pushState ou replaceState são chamados programaticamente.

Essa era termina agora. O API de navegação está aqui e está finalmente se tornando a linha de base recentemente disponível em todos os principais navegadores no início de 2026.

Uma comparação lado a lado

Para ilustrar a diferença, esta seção compara como historicamente lidamos com o roteamento do lado do cliente em comparação com a nova abordagem simplificada alimentada pela API de navegação.

A maneira antiga

// 1. Function to navigate programmatically
function navigate(path) {
  // Update the URL without a page refresh
  window.history.pushState({ path }, '', path);

  // Manually trigger the UI update
  renderContent(path);
}

// 2. Listener for browser navigation (Back/Forward buttons)
window.addEventListener('popstate', (event) => {
  // event.state contains the object we pushed in navigate()
  const path = event.state?.path || window.location.pathname;
  renderContent(path);
});

// 3. Mock UI renderer
function renderContent(path) {
  console.log(`Rendering UI for: ${path}...`);
}

// Example usage:
// navigate('/dashboard');

Como funciona a API de navegação

// 1. One central listener for ALL navigation
// This catches: links, back/forward buttons, AND programmatic calls
navigation.addEventListener('navigate', (event) => {
  const url = new URL(event.destination.url);

  // Intercept the navigation to prevent a full page reload
  event.intercept({
    async handler() {
      // The API handles the URL update; you just handle the UI
      await renderContent(url.pathname);
    }
  });
});

// 2. Mock UI renderer
async function renderContent(path) {
    console.log(`Rendering UI for: ${path}...`);
}

// Example usage:
// navigation.navigate('/dashboard');

Construir um roteador com a API History foi como montar um quebra-cabeça, pois era necessário:

  1. Ouça os cliques em tags globalmente.
  2. Chamar preventDefault() neles.
  3. Chamar manualmente history.pushState().
  4. Atualize manualmente seu DOM.
  5. Separadamente ouça o popstate evento para lidar com os botões voltar/avançar.

Se você se esquecer de lidar com um caso extremo, os usuários podem acidentalmente acabar na visão errada, destacando sua fragilidade.

A API de navegação simplifica isso radicalmente. Dá a você um único e centralizado NavegarEvento para cada navegação, seja um usuário clicando em um link, enviando um formulário, clicando no botão Voltar ou chamando seu código navigation.navigate().

O event.intercept() A função faz grande parte do trabalho pesado para você:

  • Atualizações automáticas de URL: Lida com a atualização da barra de endereço e da pilha de histórico, sem a necessidade de chamar pushState.
  • Acessibilidade automática: Lida com primitivas de acessibilidade como gerenciamento de foco (restaurando o foco após a navegação) automaticamente.
  • Lógica centralizada: Lida com o botão Voltar e clica em eventos exatamente na mesma função.

Mais alguns casos de uso

Veremos mais alguns exemplos nesta seção para destacar mais maneiras pelas quais a API de navegação pode ser aproveitada.

Exemplo: Lidando com o envio de um formulário

O evento de navegação captura automaticamente todos os envios de formulários do mesmo documento e fornece uma NavigateEvent.formData propriedade para acessar os dados.

Este exemplo captura o envio de um formulário HTML padrão, evita o recarregamento da página e processa os dados de forma assíncrona.

// 1. One central listener handles links AND forms
navigation.addEventListener('navigate', (event) => {
  // Only handle form POST submissions in this block
  if (event.formData && event.canIntercept) {
    event.intercept({
      async handler() {
        const data = event.formData;
        console.log(`Submitting form data...`);

        const username = data.get('username');

        // Perform your async API call
        postFormData(data);

        // Update UI without a page refresh
        renderSuccessMessage(username);
      }
    });
  }
});

// 2. Standard HTML form (No JS 'onsubmit' needed!)
// 
//   
//   
// 

Exemplo: Tratamento de rolagem assíncrona

Na API de navegação, event.scroll() oferece controle manual sobre quando o navegador restaura a posição de rolagem durante uma navegação.

Por padrão, o navegador tenta restaurar a posição de rolagem assim que event.intercept() é chamado. No entanto, em SPAs modernos, muitas vezes o conteúdo ainda não está pronto (você pode estar aguardando uma resposta da API). Se o navegador rolar antes de o conteúdo ser renderizado, ele irá para o lugar errado ou permanecerá no topo.

Imagine que um usuário clica no botão Voltar para retornar a uma longa lista de itens. Precisaremos buscar esses itens antes que a página tenha tempo suficiente para chegar ao fim.

navigation.addEventListener('navigate', (event) => {
  if (!event.canIntercept) return;

  event.intercept({
    // Tells the browser: "I will handle the scroll timing manually"
    scroll: 'manual',

    async handler() {
      // 1. Fetch data and render it
      const data = await fetchListData();
      renderItems(data);

      // 2. Now that the items are in the DOM and the page has height,
      //    we can move the scrollbar to the saved position (for back/forward)
      //    or to the top (for new navigations).
      event.scroll();
    }
  });
});

Exemplo: Habilitando transições de visualização

O API de navegação e Ver API de transições são projetados para trabalhar juntos para criar transições perfeitas, “semelhantes a aplicativos” em SPAs.

Ao interceptar um evento de navegação, podemos agrupar as atualizações do DOM em um document.startViewTransition(). Isso informa ao navegador para capturar um instantâneo do estado “antigo”, realizar as alterações necessárias no DOM e, em seguida, animar para o estado “novo”. Isso pode nos permitir oferecer suporte a transições semelhantes a aplicativos!

navigation.addEventListener('navigate', (event) => {
  if (!event.canIntercept) return;

  const url = new URL(event.destination.url);

  event.intercept({
    async handler() {
      // 1. Fetch the new content first (optional but recommended)
      const content = await fetchNewPageContent(url.pathname);

      // 2. Start the view transition
      document.startViewTransition(() => {
        // 3. Update the DOM inside the callback
        // The browser snapshots the old UI before this and the new UI after
        document.getElementById('app').innerHTML = content;
      });
    }
  });
});

Resumindo

Conforme visto nos exemplos anteriores, a API de navegação corrige problemas arquitetônicos profundos com a navegação em SPAs, um problema de longa data entre muitos desenvolvedores web. Ele é integrado, seguro e lida com casos extremos de maneira robusta.

No início de 2026, com suporte para Safari e Firefox, a API de navegação está pronta para o horário nobre. É o roteador que sempre desejamos: simples, poderoso e desenvolvido para a web moderna.

Written by

Categorias