Um deep link é apenas um URL que o sistema operativo entrega a uma aplicação em vez de a um browser. Toca no link num dispositivo que tem a aplicação instalada, a aplicação abre no ecrã certo. Toca-o num dispositivo sem a aplicação, o browser segue o redirecionamento para o fallback web. Um URL, dois resultados, sem shim JavaScript, sem SDK de terceiros necessário na maioria das configurações.
As equipas compram em excesso aqui com frequência. Branch.io, Adjust, AppsFlyer - os seus materiais de marketing lideram com deferred deep linking: toca no link antes de instalar a aplicação, instala, e a aplicação abre exatamente no conteúdo pelo qual tocou. Essa funcionalidade é genuinamente complexa e requer um truque de fingerprinting ou correspondência de clipboard no lado do servidor, porque o encaminhamento de links do SO está inativo até a aplicação ser instalada. Mas o deferred deep linking é apenas uma fatia do problema. O caso mais comum, "o link abre na aplicação já instalada", é resolvido inteiramente por primitivas nativas do SO que a Apple e a Google lançaram em 2015 e 2015–16 respetivamente, e que funcionam sem nada além de um domínio que controla e dois ficheiros JSON.
Esta publicação é sobre esses dois ficheiros JSON.
Resumo#
- Apple Universal Links (iOS 9+) e Android App Links (Android 6.0+) tratam do fluxo "abrir na aplicação se instalada, fallback web se não" sem SDK de terceiros.
- Ambos requerem um domínio que controla, servido via HTTPS, com um ficheiro de associação validado em
/.well-known/. O SO obtém e coloca em cache o ficheiro na instalação da aplicação, não em cada toque. - Um encurtador de URLs com um domínio personalizado como
go.acme.exampleserve ambos os ficheiros e torna-se o link que aciona o encaminhamento da aplicação - o link curto é o deep link. - O que o SDK acrescenta que as primitivas do SO não fornecem: deferred deep linking, atribuição de instalação probabilística, e ligação de identidade entre plataformas. Se precisar destas funcionalidades, o SDK justifica o custo. Se não precisar, está a pagar por funcionalidades que não usa.
As primitivas nativas do SO#
A Apple introduziu os Universal Links no iOS 9 (2015). A Android lançou os App Links no Android 6.0 Marshmallow (também 2015, distribuído para dispositivos ao longo de 2016). Ambos seguem o mesmo modelo conceptual: o SO afirma uma relação verificada entre um domínio e uma aplicação, e quando um URL nesse domínio é tocado, o SO encaminha-o para a aplicação em vez de para o browser.
A verificação é mútua e offline-first. Na instalação da aplicação, o SO obtém um ficheiro de associação do seu domínio e coloca-o em cache. O fetcher da Apple está documentado em developer.apple.com/ios/universal-links/ (consultado em 2026-05-12); o equivalente do Google está em developer.android.com/training/app-links (consultado em 2026-05-12). Nenhuma obtenção acontece no momento do toque num dispositivo quente - a cache significa que a decisão de encaminhamento não custa nenhuma ida e volta de rede.
O próprio redirecionamento é um HTTP 302 padrão. O SO interceta-o antes de o browser carregar, verifica a sua cache local, e entrega o URL à aplicação se for encontrada uma correspondência. Uma vez a cache aquecida, toda a decisão é local. A borda que serve o link curto emite o redirecionamento e o SO assume.
Os dois ficheiros#
apple-app-site-association#
O ficheiro AASA deve ser servido em https://seudominio.example/.well-known/apple-app-site-association (a Apple também verifica o caminho do ápice https://seudominio.example/apple-app-site-association por compatibilidade com versões anteriores, mas o caminho .well-known é o padrão atual). Deve ser servido via HTTPS com uma cadeia de certificados válida e com um cabeçalho Content-Type: application/json. O fetcher CDN da Apple rejeita ficheiros servidos com o Content-Type errado - este é um dos erros de configuração incorreta mais comuns em produção.
A referência completa do formato está em developer.apple.com/documentation/xcode/supporting-associated-domains.
Uma forma AASA mínima:
{
"applinks": {
"details": [
{
"appIDs": ["ABCDE12345.com.example.acme"],
"components": [
{
"/": "/spring-*",
"comment": "Match any path starting with /spring-"
},
{
"/": "/campaigns/*"
}
]
}
]
}
}
appIDs é a concatenação do seu Apple Team ID e do identificador de bundle da sua aplicação, separados por um ponto. O array components controla quais os caminhos que acionam o encaminhamento para a aplicação; qualquer coisa que não corresponda a um componente passa para o browser. Pode registar várias aplicações no array details - útil se tiver uma variante de consumidor e uma variante empresarial do mesmo produto no mesmo domínio.
Um detalhe que vale a pena declarar claramente: "/" com um padrão wildcard como /spring-* é uma correspondência de prefixo de caminho. O parser AASA da Apple suporta sintaxe de padrão definida na documentação do Xcode, incluindo * (qualquer substring), ? (qualquer caractere único), e objetos de exclusão. Se quiser corresponder a todos os caminhos no domínio, use "/" : "/*". Se quiser excluir um caminho específico do encaminhamento para a aplicação - por exemplo, a sua página /account/delete deve sempre abrir no browser - adicione um objeto de exclusão antes do wildcard:
{
"/": "/account/delete",
"exclude": true
}
As regras são avaliadas do primeiro para o último. Coloque as exclusões antes dos wildcards.
assetlinks.json#
O ficheiro Digital Asset Links do Android vive em https://seudominio.example/.well-known/assetlinks.json. A especificação é mantida pela Google em developers.google.com/digital-asset-links/v1/getting-started.
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example.acme",
"sha256_cert_fingerprints": [
"AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
]
}
}
]
package_name é o ID de aplicação da sua aplicação na Play Store. sha256_cert_fingerprints é o fingerprint SHA-256 do certificado usado para assinar o APK - não o SHA-1, não o MD5. Pode encontrar o fingerprint na Play Console em Integridade da Aplicação, ou executando keytool -list -v -keystore your.keystore. Se lançar tanto uma compilação de depuração como uma de produção, inclua ambos os fingerprints no array.
Ao contrário do ficheiro AASA, o ficheiro de associação do Android não suporta filtragem de caminhos ao nível do ficheiro. A correspondência de caminhos para App Links é feita no AndroidManifest.xml via <intent-filter> com android:pathPrefix, android:pathPattern, ou o mais recente android:pathAdvancedPattern (disponível a partir do Android 12). O ficheiro assetlinks.json afirma a propriedade do domínio; o manifesto declara quais os caminhos que a aplicação trata.
Como um encurtador de URLs se encaixa#
Um link curto como go.acme.example/spring-launch é apenas um URL num domínio. Da perspetiva do SO, se go.acme.example tem um ficheiro AASA ou assetlinks.json válido, qualquer toque num link sob esse domínio é elegível para encaminhamento para a aplicação.
Esta é a configuração que suportamos diretamente em domínios personalizados com o Elido. Quando regista go.acme.example como domínio personalizado no seu espaço de trabalho, o Elido serve o redirecionamento HTTPS para cada slug sob esse domínio. Serve os dois ficheiros de associação do mesmo domínio - seja na sua própria origem atrás de um proxy de caminho, ou via o servidor HTTPS do próprio domínio. O redirecionamento de borda é acionado; o SO interceta-o antes de o browser carregar, consulta a sua cache AASA/App Links, e abre a aplicação se for encontrada uma correspondência.
A arquitetura está descrita em mais detalhe na publicação custom-domains-for-short-links - a emissão TLS e a configuração CNAME aplicam-se aqui exatamente como descrito lá. A camada de deep link é aditiva: mesmo domínio, mesmo redirecionamento, dois ficheiros JSON por cima.
Para equipas de produto que usam links curtos para onboarding móvel - códigos de referência, links de convite, fluxos de "partilhar uma receita" - este padrão cobre quase tudo sem adicionar dependências de SDK ao binário da aplicação.
O que o SDK acrescenta#
Três capacidades que as primitivas nativas do SO não fornecem:
Deferred deep linking. Um utilizador toca no seu link antes de instalar a aplicação. No primeiro lançamento após a instalação, a aplicação abre exatamente no conteúdo pelo qual tocou. Os iOS Universal Links e Android App Links ficam silenciosos quando a aplicação não está instalada - o URL vai para o browser, a intenção perde-se. Recuperá-la requer uma correspondência de fingerprint no lado do servidor (IP + User-Agent + timestamp, probabilístico) ou o truque de clipboard do iOS. Branch, Adjust e AppsFlyer implementam ambos; os casos extremos em torno dos prompts do App Tracking Transparency e do comportamento do Safari tornam fazê-lo você mesmo não trivial.
Atribuição de instalação à escala. A rota nativa do SO dá-lhe a abertura da aplicação com o caminho do URL, mas se a aplicação não estava instalada no primeiro toque, a cadeia de atribuição está quebrada. Reconciliar cliques com instalações via SKAN no iOS e Play Install Referrer no Android é possível sem um SDK pago, mas requer trabalho de integração que os fornecedores de atribuição já fizeram.
Ligação de identidade entre plataformas. Ligar um toque a um endereço de e-mail, contacto CRM, ou sessão web. O caminho nativo do SO é anónimo da perspetiva do serviço de links. Os fornecedores de SDK mantêm um grafo de dispositivo persistente. Construir isso você mesmo é um projeto substancial de infraestrutura de dados.
Se nenhum desses três se aplicar, as primitivas do SO cobrem-no. Se um for importante, delimite-o com precisão - pode apenas precisar de deferred deep links, uma superfície de API, não o SDK completo.
Livro de receitas de configuração#
Requisitos de DNS e HTTPS#
Ambos os ficheiros devem ser servidos via HTTPS do domínio cujos links quer deep-linkar. O certificado deve encadear para uma CA raiz pública; certificados autoassinados fazem com que os fetchers de validação tanto da Apple como da Google falhem silenciosamente. Os certificados Let's Encrypt funcionam bem.
O TLS do domínio também não deve redirecionar o caminho /.well-known/ antes de servir o ficheiro. Se o seu servidor emite um redirecionamento www. antes de o fetcher da Apple conseguir chegar a https://seudominio.example/.well-known/apple-app-site-association, a obtenção falha. O fetcher da Apple segue até um redirecionamento, mas o fetcher assetlinks do Google não segue quaisquer redirecionamentos - o ficheiro deve estar no caminho exato, sem redirecionamento.
iOS: entitlement de Domínios Associados#
No Xcode, em Signing & Capabilities do seu alvo, adicione o entitlement de Domínios Associados com o valor applinks:go.acme.example. Se estiver a testar numa compilação de desenvolvimento (não distribuída via TestFlight ou App Store), adicione ?mode=developer ao valor do entitlement: applinks:go.acme.example?mode=developer. Isto diz ao SO para re-obter o AASA a cada lançamento em vez de usar a cache do momento de instalação - útil para iterar nos seus padrões de caminho sem reinstalar da Store de cada vez.
O CDN da Apple que obtém o seu ficheiro AASA é a própria infraestrutura da Apple, não o próprio dispositivo. A Apple pré-obtém e coloca em cache os ficheiros AASA do seu domínio e serve-os aos dispositivos durante a instalação da aplicação, o que significa que o ficheiro precisa de ser acessível pelos crawlers da Apple, não apenas pelo dispositivo do utilizador final. Isso também significa que existe um atraso de propagação - as alterações ao seu ficheiro AASA podem demorar horas a chegar a todos os dispositivos via cache da Apple. Para programadores que precisam de iteração rápida nos padrões de caminho, o entitlement ?mode=developer contorna o CDN da Apple e obtém diretamente do seu servidor.
Android: App Links no manifesto#
Em AndroidManifest.xml, dentro da activity que deve tratar deep links:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="go.acme.example"
android:pathPrefix="/campaigns/" />
</intent-filter>
android:autoVerify="true" diz ao Android para tentar verificar o domínio contra assetlinks.json. Sem ele, o utilizador vê um ecrã de desambiguação em cada toque em vez de uma abertura direta para a aplicação. A verificação acontece na instalação; o dispositivo contacta https://go.acme.example/.well-known/assetlinks.json e verifica se o fingerprint do certificado da aplicação instalada está listado.
Validadores e erros comuns#
A Apple fornece um validador em search.developer.apple.com/appsearch-validation-tool/ que verifica se o CDN da Apple consegue obter e analisar o seu ficheiro AASA. Introduza o seu domínio e devolve um resultado de análise válido ou um erro específico. Falhas comuns:
- Content-Type errado. Se o seu servidor devolver
text/plainouapplication/octet-stream, o validador reporta o ficheiro como ilegível mesmo que o JSON seja válido. Defina explicitamenteContent-Type: application/json. appIDsem falta ou com incompatibilidade. O prefixo de Team ID emappIDsdeve corresponder exatamente ao Team ID na sua conta de Programador Apple, incluindo maiúsculas e minúsculas. Um único caractere errado falha silenciosamente no momento do toque.- Problema na cadeia de certificados. Se o seu domínio serve um certificado que não encadeia para uma raiz pública (comum em ambientes de staging com raízes CA locais), o fetcher da Apple rejeita o ficheiro.
O validador da Google é a API Digital Asset Links: https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://go.acme.example&relation=delegate_permission/common.handle_all_urls. A resposta JSON lista todas as declarações que a Google verificou para o seu domínio. Se a resposta estiver vazia ou não contiver o seu nome de pacote, o Android não irá verificar automaticamente a aplicação na instalação. Falhas comuns:
- Redirecionamento no caminho assetlinks. Como referido: o fetcher do Google não segue redirecionamentos.
- Fingerprint de certificado errado. O APK de depuração e o APK de lançamento são assinados com chaves diferentes. Se apenas listou o fingerprint de lançamento, as compilações de depuração não verificarão. Liste ambos.
- Ficheiro servido com CORS mas cabeçalho errado para o pedido de verificação. O fetcher não se preocupa com CORS, mas algumas configurações CDN devolvem 403 em
GETde um intervalo de IP do Google se o caminho não estiver na allowlist de cache. Verifique que/.well-known/assetlinks.jsondevolve 200 a partir de um cliente HTTP externo, não apenas do seu browser.
O compromisso declarado claramente#
Remover o SDK de deep-link poupa aproximadamente 150–250KB de tamanho de binário comprimido e elimina uma chamada de API por instalação para os servidores do fornecedor de atribuição. Isso remove uma relação de partilha de dados da sua política de privacidade e pode simplificar os registos de processamento de dados RGPD. Ganhos reais, mas modestos.
O custo é que a atribuição no momento de instalação se torna aproximada ou ausente. Se um utilizador tocar no seu link antes de instalar a aplicação, verá a instalação na App Store Connect ou Play Console, mas não a ligará ao toque específico no link. Ainda pode executar experiências de smart link para comparar quais campanhas geram mais instalações - os sinais relativos sobrevivem - mas a atribuição por dispositivo e por clique requer a camada de fingerprinting do SDK.
Para equipas em escala inicial onde o CPI por canal ainda não está a impulsionar decisões de orçamento, começar com primitivas do SO é o caminho sensato. Adicione um SDK de atribuição mais tarde, quando os dados forem realmente acionáveis.
Para o guia de configuração voltado para programadores sobre a configuração de deep link do Elido, o esquema completo para o fluxo de verificação de domínio, configuração de proxy AASA, e as opções de servir assetlinks.json estão documentados lá. A página de soluções para equipas de produto cobre os casos de uso mais amplos de smart link e ligação móvel.
Marius Voß é DevRel + infraestrutura de borda no Elido. É responsável pelos serviços edge-redirect e domain-manager.
Experimente Elido
Cole uma URL, obtenha um link curto
Sem cadastro. O link vive 30 dias. Cadastre-se para mantê-lo para sempre.
Grátis, sem necessidade de registo · 2 por dia