1. Introdução
Existe um tipo de erro que raramente é identificado durante os testes. Não resulta de código incorreto, de uma validação em falta ou de uma falha de rede. Pode surgir quando um utilizador faz algo tão simples como duplicar um separador do navegador.
Ao duplicar um separador, o navegador copia o sessionStorage do separador original. Ambos partem, assim, com a mesma sessão, variáveis e contexto. A partir desse momento, porém, evoluem de forma independente: as alterações realizadas num separador não ficam visíveis no outro, e o servidor pode não reconhecer que existem duas instâncias da mesma sessão em execução.
Nas aplicações OutSystems, sobretudo quando existem processos BPT, operações de longa duração e variáveis de sessão, esta situação pode provocar encomendas duplicadas, fluxos inconsistentes ou ações executadas mais do que uma vez.
Para ilustrar o problema, utilizaremos a MyBTD, uma plataforma fictícia de supermercado online através da qual os clientes realizam encomendas e os responsáveis de loja gerem stock e fornecedores.
2. O problema: estados de sessão divergentes
Dois separadores duplicados começam com o mesmo estado, mas deixam de comunicar entre si assim que o utilizador interage com um deles.
Esta divergência acontece silenciosamente, sem apresentar erros ou avisos, e pode originar:
- Submissões duplicadas: a mesma encomenda ou processo é executado duas vezes.
- Fluxos interrompidos: um processo iniciado num separador é continuado ou cancelado noutro.
- Informação desatualizada: cada separador apresenta um estado diferente.
- Utilização incorreta de tokens: identificadores BPT ou outros dados de servidor são partilhados entre ambos.
Normalmente, estes problemas apenas se tornam visíveis em produção, quando já provocaram consequências operacionais ou financeiras.
3. Como detetar um separador duplicado
Uma deteção fiável pode ser feita através da combinação de dois comportamentos do navegador.
sessionStorage
Quando um separador é duplicado, todo o conteúdo do sessionStorage é copiado. Assim, um TabId criado no separador original também estará presente no duplicado.
window.name
A propriedade window.name mantém-se durante a navegação no mesmo separador, mas não é copiada quando este é duplicado. O novo separador começa com esta propriedade vazia.
A regra de deteção é, portanto:
sessionStorage contém um TabId e window.name está vazio → separador duplicado
Quando esta situação é identificada, o mecanismo pode:
- Registar o TabId original.
- Gerar um novo identificador para o separador duplicado.
- Comunicar o evento ao servidor através de uma API REST.
- Definir o window.name para evitar novas deteções após uma atualização.
- Impedir o registo repetido do mesmo evento num curto período.

Figura 1 – Na MyBTD, o Web Block TABDetection garante esta proteção em navegadores comuns baseados em Chromium (como Google Chrome e Microsoft Edge), com possíveis limitações no Firefox devido ao sessionStorage.
4. Estratégias de Mitigação:
A deteção, por si só, não evita o problema. É necessário definir o que acontece quando um separador duplicado é identificado.
Opção A – Bloquear o separador duplicado
Recomendada para processos críticos.
O novo separador é imediatamente redirecionado para uma página de erro, enquanto o original continua a funcionar normalmente.
Esta abordagem é especialmente adequada para checkout, pagamentos ou submissões importantes. Por exemplo, se um cliente duplicar o separador durante o pagamento, apenas o original poderá concluir a encomenda, evitando cobranças em duplicado.
A mensagem apresentada deve ser simples e clara:
Esta operação já se encontra aberta noutro separador. Continue nesse separador.
Opção B – Sincronização com BroadcastChannel
Adequada para dashboards e ecrãs de consulta.
Nem todos os casos exigem o bloqueio do separador. Em ecrãs predominantemente informativos, pode ser suficiente manter os dados sincronizados.
A API BroadcastChannel permite que vários separadores da mesma origem comuniquem entre si em tempo real. Quando um deles recebe ou altera informação, pode notificar os restantes para que atualizem os seus dados.
Num dashboard de stock, por exemplo, uma atualização recebida num separador pode ser comunicada aos outros, evitando decisões baseadas em informação desatualizada.
Opção C – localStoragecomo fonte única de verdade
Indicada para estados simples partilhados entre separadores.
Ao contrário do sessionStorage, o localStorage é comum a todos os separadores da mesma origem. Pode, por isso, ser utilizado para guardar um estado partilhado, acompanhado por um mecanismo que determine qual dos separadores pode alterá-lo.
Num cesto de compras, por exemplo, uma alteração realizada num separador pode ser detetada pelos restantes. Estes podem apresentar uma mensagem e voltar a carregar o estado mais recente.
Esta opção é simples e evita pedidos adicionais ao servidor, embora exija cuidados para prevenir alterações simultâneas.

Figura 2 – Eficaz para uma sincronização ligeira do estado, sem pedidos de ida e volta ao servidor.
Opção D – Validação do TabId no servidor

Figura 3 – A solução mais robusta para processos críticos, regulados ou auditados.
Os controlos no navegador podem ser contornados. Para garantir a integridade de um processo, a validação deve também ser realizada no servidor.
O TabId é enviado em cada pedido relevante, e o servidor confirma se o separador é o proprietário autorizado da instância do processo. Os pedidos enviados por outros separadores são rejeitados.
Em OutSystems, o identificador pode ser guardado numa variável de sessão ou num atributo do processo e validado em ações como:
- Início de processos BPT.
- Submissão de formulários.
- Aprovação de etapas.
- Gravação de dados.
- Criação de encomendas ou ordens de compra.
Esta opção acrescenta complexidade, mas oferece o nível mais elevado de proteção.
5. Comparação das estratégias

Tabela 1 – Comparação das estratégias de mitigação de separadores duplicados.
6. Recomendação
Para uma aplicação transacional como a MyBTD, recomenda-se a combinação das opções A e D.
O Web Block TABDetection pode bloquear rapidamente os separadores duplicados nos ecrãs que iniciam ou fazem avançar processos. Em paralelo, a validação do TabId no servidor deve proteger as ações mais críticas, como o início de BPT, a submissão de processos e a gravação de dados.
Esta abordagem cria uma proteção em várias camadas:
- O cliente responde rapidamente às situações mais comuns.
- O servidor garante a integridade do processo.
- Cada mecanismo funciona de forma independente.
7. Conclusão
A duplicação de separadores pode parecer um comportamento inofensivo, mas, em aplicações com estado e processos transacionais, pode originar encomendas repetidas, informação inconsistente ou fluxos executados duas vezes.
A melhor abordagem consiste em detetar a duplicação nos ecrãs relevantes, bloquear o novo separador quando o risco é elevado e aplicar validações no servidor nas operações mais críticas.
Os utilizadores que nunca duplicarem um separador não notarão qualquer diferença. Os que o fizerem receberão uma mensagem clara, em vez de provocarem silenciosamente uma situação difícil de reproduzir e resolver.
Henrique S.
OutSystems Tech Lead na Babel
