Um código QR para duas lojas de apps: uma pequena página de redirecionamento
Por Nesim Razon, desenvolvedor Android independente · 2026-11-16
Meu site tem um botão "Instalar com QR" para quem o visita pelo computador. Antes era simples, porque todos os apps eram só para Android. Depois os apps chegaram também ao iPhone e eu precisei decidir o que esse botão deveria mostrar. Terminei com um único código QR que serve para as duas lojas. Veja como funciona e quanto custa.
A pergunta: o que o botão mostra agora?
Até pouco tempo atrás o código QR continha o endereço do app no Google Play, com um parâmetro de referência para que o Play Console me dissesse quantas instalações vinham do QR. Com uma versão na App Store, um único código parecia insuficiente.
Considerei quatro opções: dois códigos QR separados, uma imagem com dois códigos lado a lado, abas que alternam entre um código do Play e outro da App Store, ou um único código universal. As três primeiras colocam uma escolha diante do visitante, e o visitante não sabe qual é a certa até já ter pegado o celular.
Por que um código basta
O botão só aparece no desktop. Na folha de estilos ele exige um dispositivo parecido com um mouse (hover e ponteiro preciso) e uma janela de pelo menos 900 pixels de largura, então celulares e tablets nunca o veem. Isso significa que quem escaneia o código está segurando exatamente o celular que deve instalar o app, e esse celular já sabe a qual loja pertence.
Por isso o código não precisa carregar a escolha. Ele só precisa carregar um endereço que faça a escolha depois que o celular o abrir.
A página de redirecionamento
O código QR aponta para um endereço curto no formato /go/<app>/ no meu site. Um pequeno script gerador escreve essa página para cada app que existe na App Store. A página faz três coisas.
Primeiro, ela lê o user agent. Se contiver iPhone, iPad ou iPod, o visitante está no iOS. Há uma pegadinha: desde o iPadOS 13 o iPad se identifica com um user agent de Mac, então um user agent de Mac junto com mais de um ponto de toque também conta como iOS. Um Mac de verdade não tem tela sensível ao toque, por isso não é pego por engano.
Segundo, ela envia o celular para a loja certa com location.replace. Escolhi replace em vez de atribuir location.href porque ele não deixa a página de redirecionamento no histórico. Caso contrário, o botão Voltar levaria de volta à minha página, que redirecionaria de novo na hora, e o visitante ficaria preso em um loop.
Terceiro, no Android ela abre o mesmo endereço do Google Play de antes, com a referência que marca a visita como vinda de um QR. Assim o detalhamento da origem das instalações no Play Console continua funcionando e eu ainda consigo ver quantas instalações vêm de códigos QR.
Alternativa no desktop e sem JavaScript
Se a página for aberta em um computador, ou o navegador não tiver JavaScript, nada é redirecionado. A página então mostra os dois selos oficiais das lojas, um do Google Play e outro da App Store, com um link para a página do app no meu site. Ninguém encontra uma página em branco, e quem compartilhar o link curto por engano ainda recebe algo útil.
A página está marcada como noindex. Ela existe para quem escaneia, não para buscadores, e não quero um monte de páginas quase idênticas nos resultados de busca.
Um código menor de bônus
O código QR agora contém um endereço curto em vez da URL longa do Play com sua referência. Menos caracteres significam um padrão menos denso, com quadrados maiores, que a câmera de um celular lê com mais facilidade de uma tela, principalmente a de um notebook em ângulo. O gerador usa a biblioteca segno com nível de correção de erros M.
Só onde existe um app para iPhone
Nem todo app tem versão para iPhone. Um pequeno arquivo JSON lista os apps que estão na App Store, e só eles recebem uma página /go/ e o código universal. Os apps só para Android mantêm um QR direto para o Google Play, sem nenhuma página intermediária.
Uma armadilha na compilação do site
A compilação do meu site divide cada página em pastas por idioma e escreve entradas no mapa do site. Ao adicionar a nova pasta /go/, a compilação a tratou como uma página normal do site e começou a gerar cópias traduzidas e linhas de mapa do site para ela. A correção foi uma única palavra: adicionar a pasta à lista de diretórios que a compilação de idiomas ignora, ao lado de pastas como as imagens de QR e os selos. Um auxiliar de redirecionamento não deveria estar no mapa do site.
Como testei e as desvantagens
Abri o endereço curto em um celular Android e ele abriu a página do Play. A leitura com a câmera de um iPhone também foi confirmada, então os dois celulares foram verificados uma vez à mão. É um teste pequeno, não um laboratório de dispositivos.
As desvantagens são as honestas. A escolha automática precisa de JavaScript; sem ele, o visitante precisa tocar em um selo. E uma página intermediária é mais um salto: um breve lampejo da minha página antes de a loja abrir e mais uma coisa que poderia quebrar, embora seja um único arquivo estático.
Perguntas frequentes
Por que não mostrar dois códigos QR, um por loja?
Porque o botão de QR só aparece no desktop, então o celular que escaneia é o que deve instalar o app. Um código e uma página que escolhe a loja poupam o visitante de uma escolha.
Como a página sabe que o celular é um iPhone?
Ela procura iPhone, iPad ou iPod no user agent. Os iPads recentes se identificam com um user agent de Mac, então um user agent de Mac com mais de um ponto de toque também conta como iOS.
Ainda vejo as instalações por QR no Google Play Console?
Sim. O destino Android mantém o endereço do Play com a referência do QR, então o detalhamento da origem das instalações continua contando essas instalações.
O que acontece sem JavaScript ou em um computador?
Não há redirecionamento. A página mostra os dois selos oficiais das lojas para o visitante escolher.
Mais do blog
- Por que meu link da App Store deu 404 e a página mostrava capturas de 2018
- Diretriz 2.1 da App Store "Information Needed": o que enviei
- Capturas de tela da App Store sem celular: Robolectric, um carregador de imagens falso e um navegador sem interface
- Reescrever para Kotlin Multiplatform sem mudar o comportamento: o código antigo como oráculo de testes
- Uma lista remota sem servidor para "Mais jogos": um arquivo JSON no GitHub Pages
- Depurar um iPhone no Windows por USB: capturas de tela e logs com Python