11 min de lectureFonctionnalités

Deep links sans SDK : Universal Links et App Links

Ouvrez votre appli depuis un lien avec deux fichiers JSON, sans SDK. Comment Universal Links et App Links fonctionnent avec un domaine de liens courts.

Marius Voß
DevRel · edge infra

Un deep link est une URL que le système d'exploitation remet à une appli plutôt qu'à un navigateur. Touchez-le avec l'appli installée et l'appli s'ouvre. Sans l'appli, le navigateur charge la page web. Sur iOS, cela s'appelle Universal Links, sur Android App Links, et aucun des deux n'exige de SDK.

La mise en place tient en deux fichiers JSON sur un domaine que vous contrôlez, plus un droit (entitlement) ou un filtre d'intention dans l'appli. Voici les deux fichiers, la place d'un domaine de liens courts, la partie que la plupart des guides omettent (l'appli reçoit l'URL courte, pas la cible de la redirection), et les trois tâches qu'un SDK fait encore mieux.

Cela compte plus qu'avant. Google a arrêté Firebase Dynamic Links le 25 août 2025, et sa FAQ renvoie désormais HTTP 404 pour ces liens (FAQ d'assistance Firebase, consultée le 2026-10-24). Cette FAQ indique un éditeur pour une parité fonctionnelle complète, et App Links plus Universal Links pour les applis qui n'ont besoin que de s'ouvrir lorsqu'elles sont installées. Pour le cas du passage de l'imprimé à l'installation, un QR code pour les téléchargements d'applis place le même routage derrière un code scannable.

En bref

  • Android App Links (Android 6, API 23, et suivants) et iOS Universal Links couvrent le cas "ouvrir dans l'appli si elle est installée, page web sinon" sans SDK tiers.
  • Chacun exige un domaine que vous contrôlez, servi en HTTPS, avec un fichier d'association sous /.well-known/.
  • Sur un domaine de liens courts, l'appli est lancée avec l'URL courte. Le code de votre appli doit la résoudre en écran. Le 302 ne s'exécute jamais.
  • Les SDK justifient encore leur coût pour le deep linking différé, l'attribution d'installation et le raccord d'identité. Passez-vous-en si vous n'en avez pas besoin.

Comment le système décide d'ouvrir votre appli

Les deux systèmes affirment une relation vérifiée entre un domaine et une appli. La documentation d'Android dit que les App Links permettent à des URL de sites vérifiées d'ouvrir "immédiatement le contenu correspondant dans votre appli Android, sans obliger l'utilisateur à choisir votre appli dans une boîte de dialogue de désambiguïsation", et que les utilisateurs sans l'appli "vont sur votre site web à la place - sans 404, sans erreurs" (developer.android.com/training/app-links/about, consulté le 2026-10-24).

Android vérifie à l'installation. Quand un filtre d'intention porte android:autoVerify="true", un appareil sous Android 6 ou plus récent vérifie les hôtes déclarés par rapport à https://hostname/.well-known/assetlinks.json pendant l'installation de l'appli (developer.android.com/training/app-links/verify-android-applinks, consulté le 2026-10-24). Attendez au moins 20 secondes pour cette vérification avant de tester. Sous Android 15 et plus récent, une revérification a aussi lieu périodiquement, et les modifications du fichier peuvent mettre jusqu'à sept jours à se propager. Android 14 et les versions antérieures ne prennent en compte les changements qu'à l'installation ou à la mise à jour.

Les pages développeur d'Apple (developer.apple.com, Supporting associated domains et Supporting universal links) ne se sont pas affichées lors de ma récupération du 2026-10-24 : je ne cite donc pas de comportement d'Apple au-delà de ce que montrent ses exemples publiés. Le fichier se trouve à /.well-known/apple-app-site-association, l'appli déclare applinks:your-domain dans son droit Associated Domains, et un Universal Link parvient à l'appli sous la forme d'une activité utilisateur de navigation web portant l'URL. Vérifiez la page Apple actuelle avant de livrer, surtout pour la mise en cache et le comportement en mode développement.

La conséquence pour les liens courts en découle directement. Le système décide à partir de l'URL touchée. Cela se produit avant toute requête vers votre serveur. Si le domaine de cette URL est vérifié pour votre appli, l'appli s'ouvre avec cette URL. Aucune requête HTTP vers le lien court n'a lieu, donc aucune redirection ne s'exécute.

Les deux fichiers

Un fichier par plateforme, chacun à un chemin fixe sur le même domaine.

apple-app-site-association

Le fichier AASA doit être servi à https://yourdomain.example/.well-known/apple-app-site-association. Servez-le en HTTPS avec une chaîne de certificats valide, un statut 200 et Content-Type: application/json, sans redirection.

La référence de format d'Apple est Supporting associated domains ; sa page ne s'est pas affichée pour moi le 2026-10-24 : considérez donc l'exemple ci-dessous comme la forme couramment publiée et vérifiez-le sur cette page.

Une forme AASA minimale :

{
  "applinks": {
    "details": [
      {
        "appIDs": ["ABCDE12345.com.example.acme"],
        "components": [
          {
            "/": "/spring-*",
            "comment": "Match any path starting with /spring-"
          },
          {
            "/": "/campaigns/*"
          }
        ]
      }
    ]
  }
}

appIDs est la concaténation de votre Team ID Apple et de l'identifiant de bundle de votre appli, séparés par un point. Le tableau components contrôle quels chemins déclenchent le routage vers l'appli ; tout ce qui ne correspond à aucun composant revient au navigateur. Vous pouvez enregistrer plusieurs applis dans le tableau details - utile si vous avez une variante grand public et une variante entreprise du même produit sur le même domaine.

Un détail à énoncer clairement : "/" avec un motif à joker comme /spring-* est une correspondance de préfixe de chemin. La syntaxe des motifs de la même référence comprend * (toute sous-chaîne), ? (tout caractère unique) et des objets d'exclusion. Si vous voulez faire correspondre tous les chemins du domaine, utilisez "/" : "/*". Si vous voulez exclure un chemin précis du routage vers l'appli - par exemple votre page /account/delete doit toujours s'ouvrir dans le navigateur - ajoutez un objet d'exclusion avant le joker :

{
  "/": "/account/delete",
  "exclude": true
}

Les règles sont évaluées de la première à la dernière : placez donc les exclusions avant les jokers.

assetlinks.json

Le fichier Digital Asset Links d'Android se trouve à https://yourdomain.example/.well-known/assetlinks.json. Google documente le format sur 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 est l'identifiant d'application de votre appli sur le Play Store. sha256_cert_fingerprints contient les empreintes SHA-256 du certificat de signature de votre appli (la page de Google dit que les cibles d'applis mobiles sont identifiées par le hachage du certificat et le nom du paquet). Obtenez-la avec keytool -list -v -keystore your.keystore, ou depuis les réglages de signature de votre Play Console si Play signe l'appli pour vous. Listez chaque certificat avec lequel vous installez des builds, y compris celui de débogage.

Contrairement au fichier AASA, le fichier Android ne comporte aucune règle de chemin. La correspondance des chemins pour les App Links se fait dans le AndroidManifest.xml via <intent-filter> avec android:pathPrefix, android:pathPattern. Le fichier assetlinks.json affirme la propriété du domaine ; le manifeste déclare quels chemins l'appli gère.

Séquence de résolution AASA : toucher d'un lien court, récupération par le système à la première installation, succès du cache aux touchers suivants

La place d'un domaine de liens courts

Un lien comme go.acme.example/spring-launch n'est qu'une URL sur un domaine. Donnez à go.acme.example les deux fichiers d'association et déclarez-le dans l'appli, et un toucher sur ce lien ouvre l'appli sur les appareils où elle est installée. C'est l'astuce, et aussi le piège. L'appli reçoit https://go.acme.example/spring-launch, pas la page vers laquelle le lien redirige.

Le code de votre appli a alors deux options. Une : faire correspondre le chemin lui-même (/spring-launch signifie l'écran du printemps), ce qui fonctionne quand vous contrôlez les slugs. Deux : demander à un serveur vers quoi pointe le lien court et router d'après la réponse. Elido n'a aucun point d'accès documenté permettant à une appli de résoudre un slug en sa cible. La redirection publique répond simplement par un 302. Aujourd'hui, la première option est la fiable, et cette lacune figure dans notre backlog.

Sur les appareils sans l'appli, ou quand le toucher a lieu dans un endroit qui ne transmet pas les liens au système, le lien court se comporte comme toujours. L'edge répond par la redirection (302 par défaut ; un lien peut être réglé sur 301 ou 307), et le navigateur la suit. Les règles de ciblage d'Elido peuvent porter sur le système d'exploitation : un même lien peut donc envoyer les visiteurs iOS vers une page de l'App Store et les visiteurs Android vers Google Play quand l'appli n'est pas là.

Voici ce qu'Elido fait et ne fait pas aujourd'hui pour cela, vérifié dans le code :

FonctionÉtatOù
Servir apple-app-site-association pour un domaine personnaliséOuiColler le JSON par domaine dans le tableau de bord
Servir assetlinks.json pour un domaine personnaliséOuiMême panneau
Renvoyer 404 quand un domaine n'a aucun fichier configuréOuiLes domaines sans appli n'exposent rien
Router les visiteurs iOS et Android vers des URL différentesOuiRègles de ciblage (correspondance de système)
Deep linking différé après installationNonUtiliser le SDK d'un éditeur
Attribution d'installation par clicNonConsoles des stores ou un éditeur

Elido stocke le JSON que vous rédigez et le sert sans modification sous les propres chemins /.well-known/ du domaine. Elido ne génère pas pour vous le Team ID, l'identifiant de bundle ni l'empreinte du certificat de signature ; ils viennent de votre compte Apple Developer et de votre clé de signature. La configuration du domaine lui-même (CNAME et TLS) est la même que dans les liens courts à domaine personnalisé, et la page de la fonction deep links montre le parcours dans le tableau de bord. Pour les équipes produit qui utilisent des liens courts pour l'accueil des utilisateurs, ce schéma couvre les liens d'invitation et de parrainage sans ajouter de SDK au binaire. La moitié du problème où rien n'est encore installé est ce que traitent les App Clip Codes sur iOS.

Ce qu'un SDK fait encore mieux

Trois choses sortent de ce que le système d'exploitation fournit.

Le deep linking différé. Un utilisateur touche avant d'installer. Le système n'a pas d'appli à qui remettre l'URL : le toucher va donc au navigateur et l'intention est perdue. Les éditeurs la récupèrent par une correspondance probabiliste sur les données de requête ou un passage par le presse-papiers. L'invite de consentement au pistage d'Apple rend les cas limites pénibles. Elido ne le fait pas aujourd'hui.

L'attribution d'installation. Sans SDK, vous pouvez encore voir les installations dans App Store Connect et la Play Console, mais vous ne pouvez pas en relier une à un toucher de lien précis. Des signaux relatifs subsistent : menez des expériences de liens intelligents et comparez les installations par campagne. L'attribution par appareil exige un éditeur.

Le raccord d'identité. Relier un toucher à une adresse e-mail ou à un contact CRM est un projet de données. Les éditeurs entretiennent pour cela un graphe d'appareils.

Si aucune de ces trois choses ne compte, les primitives du système suffisent. Si l'une compte, engagez l'éditeur pour cette seule tâche.

Matrice de fonctions : les primitives natives du système et un SDK payant ouvrent tous deux l'appli et se replient sur le web, mais seul le SDK ajoute le deep linking différé, l'attribution d'installation par clic et un graphe d'identité multiplateforme

Livre de recettes de configuration

Trois endroits à bien régler : le serveur, le projet iOS et le manifeste Android.

Exigences HTTPS et de chemin

Servez les deux fichiers en HTTPS avec un certificat chaîné à une autorité racine publique. La page Digital Asset Links de Google dit que la liste de déclarations "doit" se trouver à /.well-known/assetlinks.json et que des listes placées ailleurs ou sous d'autres noms ne sont pas valides (developers.google.com/digital-asset-links/v1/getting-started, consulté le 2026-10-24). Cette page ne dit pas si les redirections sont suivies : servez donc le fichier directement avec un 200 et ne jouez pas votre chance. Le même conseil s'applique au fichier Apple.

iOS : le droit Associated Domains

Dans Xcode, sous Signing & Capabilities, ajoutez la capacité Associated Domains avec la valeur applinks:go.acme.example. Apple documente un suffixe ?mode=developer pour les builds de développement qui fait récupérer le fichier par l'appareil depuis votre serveur plutôt que par le cache d'Apple ; je n'ai pas pu revérifier cette page le 2026-10-24, confirmez-le donc dans la documentation d'Apple. Gérez le lien entrant comme une activité utilisateur de navigation web (SwiftUI onContinueUserActivity(NSUserActivityTypeBrowsingWeb), ou le délégué UIKit continue userActivity) et lisez webpageURL.

Dans l'activité qui doit gérer les liens :

<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 retient pour la vérification automatique les filtres ayant l'action VIEW, les deux catégories ci-dessus et un schéma http ou https. Sous Android 11 et antérieur, le système ne fait de votre appli le gestionnaire par défaut que s'il trouve un fichier Digital Asset Links pour chaque hôte du manifeste : un seul mauvais hôte les fait donc tous échouer. Sur un appareil donné, une seule appli peut être associée à un domaine à la fois.

Vérifier que cela fonctionne

Sur Android, laissez la vérification au moins 20 secondes après l'installation, puis exécutez adb shell pm get-app-links com.example.acme (Android 12 et suivants) et cherchez verified. Vous pouvez forcer une nouvelle exécution avec adb shell pm verify-app-links --re-verify com.example.acme. Des résultats comme none, denied ou legacy_failure signifient que le fichier ou l'empreinte est faux.

Pour le fichier lui-même, l'API Digital Asset Links de Google liste les déclarations qu'elle peut lire pour un site : https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://go.acme.example&relation=delegate_permission/common.handle_all_urls. Une réponse vide signifie qu'Android ne vérifiera pas l'appli.

Pour les deux plateformes, récupérez le fichier comme le ferait un robot :

curl -si https://go.acme.example/.well-known/assetlinks.json | head -20
curl -si https://go.acme.example/.well-known/apple-app-site-association | head -20

Vous voulez un 200 et un corps JSON. Elido envoie application/json pour les deux fichiers. Les erreurs habituelles sont une faute de frappe dans le Team ID ou l'identifiant de bundle, un build de production dont le certificat de signature ne figure pas dans la liste des empreintes, et un fichier qui n'existe que sur le domaine racine alors que les liens utilisent un sous-domaine.

Le compromis, énoncé clairement

Abandonner le SDK de deep linking retire une dépendance du binaire de l'appli et une relation de partage de données de votre notice de confidentialité. Je ne donnerai pas de chiffre de taille ; il varie selon l'éditeur et je n'en ai pas mesuré. Le coût : un toucher avant installation ne peut pas être relié à l'installation.

Pour les équipes en phase de démarrage où le coût par installation et par canal ne pilote pas encore le budget, commencez par les primitives du système et ajoutez un éditeur d'attribution lorsque la donnée devient exploitable.

Sur le même sujet

Questions fréquentes

Puis-je faire du deep linking sans Firebase ni SDK tiers ?

Oui, pour le cas où l'appli est déjà installée. Les Universal Links iOS et les App Links Android exigent un domaine que vous contrôlez, un fichier d'association JSON sur ce domaine et quelques lignes dans l'appli. La FAQ de Firebase Dynamic Links de Google renvoie elle-même à ces deux mécanismes pour le deep linking vers des applis installées. Ce que vous abandonnez, c'est le deep linking différé, c'est-à-dire l'ouverture du bon écran après une nouvelle installation.

Les Universal Links et les App Links fonctionnent-ils avec un domaine de liens courts ?

Oui, si le domaine de liens courts sert les fichiers d'association et que l'appli déclare ce domaine. Le piège est que le système d'exploitation ouvre l'appli avec l'URL courte touchée elle-même : l'appli doit donc transformer cette URL en écran. Elle ne peut pas compter sur l'exécution de la redirection. Quand l'appli n'est pas installée, le même toucher se charge dans le navigateur et la redirection normale s'applique.

Où placer les fichiers d'association ?

Android lit https://your-domain/.well-known/assetlinks.json, et la documentation Digital Asset Links de Google dit que c'est le seul emplacement valide. Le fichier d'Apple se place à https://your-domain/.well-known/apple-app-site-association sans extension de fichier. Servez les deux en HTTPS avec un certificat chaîné à une autorité de certification publique.

Pourquoi mon appli Android affiche-t-elle un sélecteur au lieu de s'ouvrir directement ?

L'ouverture directe exige un App Link vérifié. Android vérifie le domaine par rapport à assetlinks.json à l'installation de l'appli, et seulement si un filtre d'intention porte android:autoVerify="true". Si le fichier est absent, erroné, ou liste un certificat de signature différent de celui de la version installée, le lien se comporte comme un deep link ordinaire.

Qu'est-ce que le deep linking différé et puis-je m'en passer ?

Le deep linking différé transporte la destination d'un lien à travers une installation d'appli, de sorte qu'un utilisateur qui touche avant d'installer arrive quand même sur le bon écran au premier lancement. Les Universal Links et les App Links ne font rien dans ce cas, car l'appli n'est pas là pour recevoir le toucher. Vous pouvez vous en passer pour des parcours d'accueil où arriver sur l'écran d'accueil convient, et n'ajouter un éditeur que si le routage au premier lancement fait bouger vos chiffres.

Quelles parties de tout cela Elido gère-t-il ?

Elido sert les fichiers apple-app-site-association et assetlinks.json pour les domaines personnalisés, à partir du JSON que vous collez dans les réglages du domaine du tableau de bord. Il route aussi les visiteurs iOS et Android vers des destinations différentes grâce aux règles de ciblage. Il ne propose ni deep linking différé ni attribution d'installation : utilisez le SDK d'un éditeur si vous en avez besoin.

Essayer Elido

Collez une URL, obtenez un lien court

Sans inscription. Lien actif 30 jours. Inscrivez-vous pour le garder pour toujours.

Sans inscription. Créez un compte gratuit pour 50 liens par mois.

Essayer Elido

Raccourcisseur d'URL hébergé en UE : domaines personnalisés, analyses approfondies et API ouverte. Forfait gratuit - sans carte bancaire.

Tags
mobile deep linking
universal links
app links android
deep linking without sdk
apple app site association
digital asset links

Lire la suite