Os links entre Páginas
Uma Página leva a outra por um link comum, com o caminho da Página de destino (veja
O caminho). O / é a Página inicial.
Um link
<a href="/cobrancas">Cobranças</a>
<a href="/">Início</a>
Escreva só o caminho, começando com /, sem o endereço do site: o construtor e o app põem o resto. Um caminho que não
é de nenhuma Página abre "Página não encontrada", com o botão Ir para o início.
Os parâmetros
O que a Página de destino precisa saber vai depois do ?, e ela lê com URLSearchParams.
Na lista, um link por cliente:
<a href="/cliente?id=7">Acme</a>
Na Página /cliente, o id:
<p>Cliente <span id="id"></span></p>
<script>
const id = new URLSearchParams(location.search).get('id'); // '7', sempre texto
document.getElementById('id').textContent = id ?? '(nenhum)';
</script>
O valor vem como texto. Sem o parâmetro, get() devolve null: trate os dois casos.
Navegar pelo código
Quando o clique não é num link (uma linha de tabela, um card), navegue com location.href, e ponha no elemento o
data-href com o mesmo caminho:
<table>
<tbody>
<tr data-href="/cliente?id=7"><td>Acme</td><td>R$ 1.500,00</td></tr>
<tr data-href="/cliente?id=8"><td>Beta</td><td>R$ 980,00</td></tr>
</tbody>
</table>
<script>
document.querySelectorAll('tr[data-href]').forEach((linha) => {
linha.style.cursor = 'pointer';
linha.addEventListener('click', () => {
location.href = linha.dataset.href;
});
});
</script>
O data-href é uma dica: com ele, o app começa a carregar a Página de destino quando o botão do mouse desce, e a troca
fica mais rápida. Sem ele, funciona igual, só mais devagar.
Um <a href> troca de Página sem piscar. A navegação pelo código (location.href) deixa o bloco em branco por um
instante no app, até a Página seguinte ficar pronta. Um link clicado pelo código (link.click()) não pisca: numa
linha clicável, ponha um link dentro dela e clique nele.
Um location.href que roda sozinho ao abrir a Página (um redirecionamento) faz o bloco parar no canvas, com "Este
bloco parou.".
Abrir numa aba nova
Um link com target="_blank", ou o window.open(), para uma Página do workflow abre uma aba nova:
<a href="/relatorio?mes=2026-10" target="_blank">Abrir o relatório numa aba nova</a>
- No app, a aba nova abre o app naquela Página.
- No "ver", a aba nova abre o construtor, com o "ver" naquela Página.
Um link para outro site não abre, nem com target: o endereço aparece como bloqueado (veja
O selo). O window.open() devolve sempre null.
Voltar
O history.back() do HTML é o Voltar da janela: volta à Página de antes. Na primeira Página do "ver", fecha o
"ver".
<button type="button" onclick="history.back()">Voltar</button>
Sair
O caminho /sair faz o logout de quem usa, como o "Sair" do construtor. Quem entra de novo cai no /.
<a href="/sair">Sair</a>
Por isso nenhuma Página pode ter o caminho sair.
Outro workflow
No app, um caminho que começa com o id de outro workflow publicado do cliente (/<id>/ e /<id>/<caminho>) abre
aquele workflow. O "ver" só conhece as Páginas deste workflow: ali, esse link dá "Página não encontrada".
Os formulários
Funciona: o formulário que o próprio script trata, com preventDefault() e um fetch para um endpoint (veja o
exemplo em Chamar a API). A Página fica onde está.
Funciona: um formulário GET para o caminho de uma Página. Ele abre a Página com os campos nos parâmetros.
<form action="/clientes" method="get">
<input name="busca" placeholder="Nome do cliente">
<button>Buscar</button>
</form>
<!-- Abre /clientes?busca=<o que foi digitado> -->
Não funciona: um formulário que o navegador mandaria sozinho, com method="post" ou para outro site. Nada sai, e o
endereço aparece como bloqueado.
<form action="/api/ops/teste-clientes" method="post">
<input name="nome">
<button>Salvar</button>
</form>
Um <form method="dialog"> dentro de um <dialog> só fecha o diálogo, como no navegador.