Recentemente eu estava trabalhando em um projeto com o seguinte fluxo:

Página de produto -> Confirmação de endereço -> Checkout

O problema era: eu precisava evitar que os usuários que clicassem no botão de voltar do navegador no contexto do checkout, voltassem para a confirmação de endereço. Depois de pensar e pesquisar um pouco, a API Window.history e seu método pushState conseguiram resolver o meu problema.

window.history.pushState(state, title, url);

O funcionamento é bem simples, podemos adicionar um estado com dados que possam nos ajudar, um título e a URL que vai estar associado à esse estado. De acordo com a documentação o comportamento é muito similar ao window.location, mas com a vantagem

Agora eu só precisava saber aonde encaixar o código pra fazer toda a mágica. O fluxo de confirmação de endereço tinha alguma ações que o usuário poderia tomar, mas todas elas tinham um comportamento parecido (uma requisição assíncrona que redirecionava para o checkout quando resolvida). Então, conclui que o lugar perfeito para encaixar a funcionalidade era antes do window.location.href, como mostro abaixo:

redirect() {
  // O document.referrer me retorna a url que original
  // que gerou o request pra atual
  const originPath = document.referrer

  // O método pushState vai adicionar o originPath no window.history
  // fazendo com que a url anterior a do checkout seja de fato o originPath
  window.history.pushState(null, null, originPath)

  // Redirecionamento
  window.location.href = '/<SOME_PATH>'
}

Obs: Os parâmetros state e title ficaram o com o valor null pois não eram necessário para mim. Mas como mencionado acima, você pode associar o que precisar no estado, caso faça sentido. Vale lembrar também que o Firefox ignora o parâmetro do título.

Finalmente, quando o usuário clicar no botão de voltar do navegador no contexto do checkout, a página que será mostrada é a de produto.