Universal links e App Links do Android: configuração do site

Configure universal links e android app links: arquivos apple-app-site-association e assetlinks.json, regras do servidor, verificações e alternativas.

Neste artigo

Os universal links (iOS) e os App Links do Android abrem o seu aplicativo em vez do site quando alguém toca em um link https:// comum, e a parte do site são dois arquivos JSON que você mesmo hospeda: apple-app-site-association para iOS e assetlinks.json para Android. Os dois ficam em /.well-known/ em cada domínio que o aplicativo atende, os dois precisam ser servidos por HTTPS sem redirecionamentos, e cada um indica qual aplicativo tem permissão para abrir as suas URLs. O aplicativo também precisa de uma configuração própria (uma permissão no iOS, um intent filter no Android), mostrada abaixo ao lado de cada arquivo.

Os dois sistemas conectam um site e um aplicativo nos dois sentidos: o aplicativo declara quais domínios atende, e o site confirma. A Apple descreve os universal links como links HTTP ou HTTPS comuns, então uma única URL funciona para o site e para o aplicativo, e os usuários sem o aplicativo recebem a página no navegador (Apple). Os App Links do Android, nas palavras do Google, usam o mesmo sistema de intents dos outros deep links, mas acrescentam uma etapa de verificação com um arquivo Digital Asset Links no seu site (Android Developers).

Universal links no iOS App Links no Android
Arquivo no site apple-app-site-association assetlinks.json
Local https://<domínio>/.well-known/apple-app-site-association https://<domínio>/.well-known/assetlinks.json
O que o aplicativo declara Permissão Associated Domains, applinks:<domínio> Intent filter com android:autoVerify="true"
Identifica o aplicativo por Team ID mais bundle ID Nome do pacote mais a impressão digital do certificado de assinatura
Quando é verificado Na instalação, pelo CDN da Apple Na instalação, e em segundo plano no Android 15 ou superior
Universal links e App Links precisam dos dois lados: o app declara o domínio (Associated Domains ou um intent filter com autoVerify) e o site hospeda um arquivo em .well-known (apple-app-site-association ou assetlinks.json)

«Deep link» é o termo mais amplo. Um deep link comum pode usar um esquema personalizado ou um link https:// não verificado; os universal links e os App Links são a versão verificada.

O arquivo do iOS: apple-app-site-association

Crie um arquivo chamado apple-app-site-association, sem extensão, e liste os identificadores do seu aplicativo e os padrões de URL que o aplicativo deve abrir. Esta é a estrutura de exemplo da documentação da Apple, resumida:

{
  "applinks": {
    "details": [
      {
        "appIDs": ["ABCDE12345.com.example.app"],
        "components": [
          { "/": "/buy/*", "comment": "Open URLs that start with /buy/ in the app." },
          { "/": "/help/website/*", "exclude": true, "comment": "Keep these in the browser." }
        ]
      }
    ]
  }
}

O valor de appIDs é o prefixo do identificador do aplicativo (o seu Team ID), um ponto e o bundle identifier. Cada entrada de components corresponde a uma parte da URL, e "exclude": true diz ao sistema para não abrir no aplicativo as URLs correspondentes (Apple, Supporting associated domains). A Apple também aceita um formato mais antigo com appID e paths; a nota de depuração dela pede que não se misture os dois (TN3155).

Publique em https://<nome de domínio completo>/.well-known/apple-app-site-association com um certificado válido e sem redirecionamentos. Três regras das páginas da Apple costumam dar problema:

  • Cada subdomínio precisa de uma entrada própria no aplicativo. Um arquivo em example.com atende applinks:example.com e applinks:*.example.com, mas um subdomínio específico como www.example.com precisa do próprio arquivo.
  • O arquivo precisa ser acessível de qualquer endereço IP e para qualquer user agent. Um 403 ou 404 vindo de um firewall, de um filtro de bots ou de uma tela de login impede os servidores da Apple de armazená-lo em cache.
  • Desde o iOS 14, os dispositivos não buscam o arquivo no seu servidor. O CDN da Apple baixa e armazena o arquivo, os dispositivos verificam atualizações cerca de uma vez por semana, e não há como invalidar esse cache diretamente; reinstalar o aplicativo baixa uma cópia mais nova (TN3155).

Durante o desenvolvimento, você pode acrescentar ?mode=developer à entrada da permissão (applinks:example.com?mode=developer) para que o dispositivo leia o arquivo diretamente do seu servidor em vez do CDN da Apple.

O arquivo do Android: assetlinks.json

O assetlinks.json é um array de declarações que nomeia o seu pacote e a impressão digital SHA-256 do certificado que assina o aplicativo. Este é o exemplo do Google para um aplicativo:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Substitua o nome do pacote e a impressão digital pelos seus. Os requisitos, segundo o guia do Google (atualizado em 23 de outubro de 2026):

  • Sirva em https://<domínio>/.well-known/assetlinks.json com o tipo de conteúdo application/json.
  • Use HTTPS mesmo que os intent filters do aplicativo também declarem http.
  • Sem redirecionamentos, nem 301 nem 302.
  • Publique em cada domínio hospedeiro que o aplicativo atende.
  • Um único arquivo pode listar vários aplicativos, e o campo sha256_cert_fingerprints aceita várias impressões digitais, por exemplo para as builds de depuração e de produção.

Se você usa o Play App Signing, a impressão digital que você obtém com o keytool na sua máquina normalmente não vai coincidir com a dos dispositivos dos usuários. O Google orienta pegar o trecho JSON correto no Play Console, em Release > Setup > App signing.

O lado do aplicativo é um intent filter com autoVerify. Esta é a forma da documentação do Android:

<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="http" />
    <data android:scheme="https" />
    <data android:host="www.example.com" />
</intent-filter>

O Android verifica cada nome de host desses filtros, e um host curinga como *.example.com exige o arquivo no domínio raiz example.com (Android Developers). No Android 15 ou superior, a verificação também roda periodicamente, e uma alteração no arquivo pode levar até sete dias para se propagar; no Android 14 ou inferior, o arquivo só é lido na instalação ou na atualização (Android Developers).

Lista de verificação do servidor

Os dois arquivos falham pelos mesmos poucos motivos, então verifique o servidor uma vez para os dois:

Verificação Por quê Como testar
HTTPS As duas plataformas exigem, e a Apple pede um certificado válido Abra a URL em um navegador
Sem 301 nem 302 Redirecionamentos não são aceitos em nenhum dos dois arquivos curl -sI mostra um 200
iOS: público para todos os IPs e user agents O CDN da Apple baixa o arquivo, e um firewall ou filtro de bots o bloqueia curl -A "MyAgent-Bot/1.0" <url> devolve o arquivo
Android: Content-Type: application/json O Google lista como requisito Cabeçalho do curl -sI
O mesmo arquivo em cada domínio e subdomínio listado Cada host é verificado separadamente Rode a verificação para cada host

Para o tipo de conteúdo, servir os dois arquivos como application/json mantém a configuração uniforme. A documentação da Apple não indica um tipo de conteúdo para o arquivo do iOS, então esse ponto é uma escolha sua. Um exemplo estático para nginx:

location = /.well-known/apple-app-site-association {
    default_type application/json;
}
location = /.well-known/assetlinks.json {
    default_type application/json;
}

Como verificar que funciona

Confira o arquivo por fora e depois o comportamento em um dispositivo. Os passos de depuração da Apple, do TN3155:

  1. Rode curl -v https://<domínio>/.well-known/apple-app-site-association e confirme um 200 e o JSON, não um 301, 302, 403 ou 404.
  2. Em um Mac, sudo swcutil dl -d <domínio> verifica se o arquivo baixa, e sudo swcutil verify -d <domínio> -j <caminho-do-JSON> -u <URL> verifica se uma URL corresponde a um padrão.
  3. Em um iPhone, cole o link no app Notas e mantenha pressionado. Se tudo estiver configurado, aparecem as opções de abrir no aplicativo e de abrir no navegador.

Para o Android, a verificação manual do Google no Android 12 ou superior (para um aplicativo que mira uma versão anterior ao Android 12, primeiro rode adb shell am compat enable 175408749 com.example):

adb shell pm set-app-links --package com.example 0 all
adb shell pm verify-app-links --re-verify com.example
# aguarde alguns minutos e depois:
adb shell pm get-app-links com.example

A saída lista cada domínio com um estado como verified ou legacy_failure. O Google também oferece um gerador e testador de listas de declarações (ferramenta Digital Asset Links) para testar um arquivo de declarações existente. Para uma rotina de testes mais ampla, veja a lista de testes de site mobile.

Digitar uma URL na barra de endereços do navegador nunca abre o aplicativo no iOS, porque é navegação direta dentro do navegador; se o usuário já está no seu domínio, um link para o mesmo domínio também fica no Safari (TN3155). A solução da Apple para fluxos como um botão de login é usar outro subdomínio, com entrada applinks e arquivo AASA próprios, para que o sistema trate o toque como uma saída do site.

Os navegadores embutidos em aplicativos precisam de testes separados. A Apple informa que links tocados em um app de navegador ou em um WKWebView podem abrir o seu aplicativo, mas também diz que navegadores de terceiros decidem se ativam os universal links («Os universal links podem não estar ativados em todos os navegadores web», segundo o TN3155), e que um aplicativo que abre o seu link pela própria chamada open(_:) não abrirá o seu link de volta (Apple). Se o navegador de um aplicativo social específico entrega o link ao seu aplicativo não é algo que a documentação da plataforma cobre, então teste cada um que importa em um celular real.

Um banner de aplicativo inteligente é um aviso exclusivo do iOS na página web: uma tag meta no <head> de cada página onde você quiser. Segundo a Apple, ele abre o aplicativo se ele estiver instalado e leva à App Store se não estiver.

<meta name="apple-itunes-app" content="app-id=myAppStoreID, app-argument=https://example.com/buy/42">

O app-id é obrigatório, e o app-argument opcional passa uma URL ao aplicativo para abrir a tela correspondente. A Apple lista dois limites: os banners não aparecem dentro de um frame, e não aparecem no simulador do iOS.

Se você não publica um aplicativo nativo, não precisa de nenhum dos dois arquivos; um aplicativo web progressivo é instalado pelo navegador.

Confira a página de contingência em tamanhos de celular

Todos que não têm o aplicativo, e todo link que não é repassado, chegam à sua página web, então essa página precisa funcionar no celular. O Mobile View Extension recarrega a aba com o user agent, o tamanho de tela e a densidade de pixels de um celular, então você vê a versão mobile real da página de contingência em vários tamanhos, e pode usar junto a emulação de dispositivo do Chrome. Ele não consegue testar a passagem para o aplicativo: roda o Chrome de desktop, não tem eventos de toque nem aplicativos instalados, então o tratamento de links exige um iPhone ou um celular Android, ou o simulador do iOS ou o emulador do Android. Para iOS sem hardware, veja testar um site em um iPhone sem ter um iPhone.

Perguntas frequentes

Deep links é a categoria ampla; universal links é a versão verificada da Apple, construída sobre links HTTP ou HTTPS padrão. Um deep link também pode usar um esquema de URL personalizado, que não está ligado a um site que você controla. Os App Links do Android são a forma verificada no Android, que acrescenta a verificação Digital Asset Links aos deep links comuns.

Onde fica o apple-app-site-association?

Fica em https://<domínio>/.well-known/apple-app-site-association, sem extensão de arquivo, servido por HTTPS com um certificado válido e sem redirecionamentos. Cada subdomínio listado pelo aplicativo precisa de sua própria cópia.

As causas comuns são um redirecionamento, um 403 ou 404 no arquivo, uma entrada de subdomínio faltando ou um toque em link do mesmo domínio. A Apple lista essas causas no TN3155; digitar a URL na barra de endereços ou tocar em um link para o mesmo domínio enquanto navega no Safari mantém o usuário no navegador. Confira o arquivo com curl -v primeiro.

Preciso dos dois arquivos?

Você precisa do arquivo de cada plataforma para a qual publica um aplicativo. Um site com um aplicativo para iOS e outro para Android serve os dois, e cada um é independente do outro.

Veja seu próximo site na versão mobile.

Adicione a extensão e abra prévias de aparelhos na mesma aba em que você já está trabalhando.