Les universal links (iOS) et les App Links Android ouvrent votre application au lieu de votre site web quand quelqu’un touche un lien https:// ordinaire. La partie du site web tient en deux fichiers JSON que vous hébergez vous-même : apple-app-site-association pour iOS et assetlinks.json pour Android. Les deux se trouvent sous /.well-known/ sur chaque domaine que gère l’application, les deux doivent être servis en HTTPS sans redirection, et chacun désigne l’application autorisée à ouvrir vos URL. L’application a aussi besoin de son propre réglage (un droit sur iOS, un filtre d’intent sur Android), présenté plus bas à côté de chaque fichier.
Comment fonctionnent les universal links et les App Links Android
Les deux systèmes relient un site web et une application dans les deux sens : l’application déclare les domaines qu’elle gère, et le site web le confirme. Apple décrit les universal links comme des liens HTTP ou HTTPS standard, si bien qu’une seule URL sert au site et à l’application, et que les utilisateurs sans l’application reçoivent la page dans leur navigateur (Apple). Les App Links Android, selon Google, reposent sur le même système d’intents que les autres deep links, mais ajoutent une étape de vérification avec un fichier Digital Asset Links sur votre site web (Android Developers).
| Universal links iOS | App Links Android | |
|---|---|---|
| Fichier sur le site web | apple-app-site-association |
assetlinks.json |
| Emplacement | https://<domaine>/.well-known/apple-app-site-association |
https://<domaine>/.well-known/assetlinks.json |
| Ce que déclare l’application | Droit Associated Domains, applinks:<domaine> |
Filtre d’intent avec android:autoVerify="true" |
| Identifie l’application par | Team ID et bundle ID | Nom de paquet et empreinte du certificat de signature |
| Quand le contrôle a lieu | À l’installation, via le CDN d’Apple | À l’installation, et en arrière-plan sur Android 15 et plus |

« Deep link » est le terme général. Un deep link simple peut utiliser un schéma personnalisé ou un lien https:// non vérifié ; les universal links et les App Links en sont la forme vérifiée.
Le fichier iOS : apple-app-site-association
Créez un fichier nommé apple-app-site-association, sans extension, et listez les identifiants de votre application et les motifs d’URL que l’application doit ouvrir. Voici la structure d’exemple de la documentation d’Apple, abrégée :
{
"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." }
]
}
]
}
}
La valeur de appIDs est le préfixe de l’identifiant d’application (votre Team ID), un point, puis le bundle identifier. Chaque entrée de components correspond à une partie de l’URL, et "exclude": true indique au système de ne pas ouvrir dans l’application les URL correspondantes (Apple, Supporting associated domains). Apple accepte aussi un format plus ancien avec appID et paths ; sa note de débogage demande de ne pas mélanger les deux (TN3155).
Hébergez-le à https://<nom de domaine complet>/.well-known/apple-app-site-association, avec un certificat valide et sans redirection. Trois règles des pages d’Apple piègent souvent :
- Chaque sous-domaine a besoin de sa propre entrée dans l’application. Un fichier sur
example.comsert pourapplinks:example.cometapplinks:*.example.com, alors qu’un sous-domaine précis commewww.example.coma besoin de son propre fichier. - Le fichier doit être accessible depuis n’importe quelle adresse IP et pour n’importe quel user agent. Un 403 ou un 404 venant d’un pare-feu, d’un filtre de bots ou d’un mur de connexion empêche les serveurs d’Apple de le mettre en cache.
- Depuis iOS 14, les appareils ne vont pas chercher le fichier sur votre serveur. Le CDN d’Apple le télécharge et le met en cache, les appareils vérifient les mises à jour environ une fois par semaine, et il n’existe pas de moyen direct d’invalider ce cache ; réinstaller l’application télécharge une copie plus récente (TN3155).
Pendant le développement, vous pouvez ajouter ?mode=developer à l’entrée du droit (applinks:example.com?mode=developer) pour que l’appareil lise le fichier directement sur votre serveur au lieu du CDN d’Apple.
Le fichier Android : assetlinks.json
assetlinks.json est un tableau de déclarations qui nomme votre paquet et l’empreinte SHA-256 du certificat qui signe l’application. Voici l’exemple de Google pour une application :
[{
"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"]
}
}]
Remplacez le nom du paquet et l’empreinte par les vôtres. Les exigences, selon le guide de Google (mis à jour le 23 octobre 2026) :
- Servez-le à
https://<domaine>/.well-known/assetlinks.jsonavec le type de contenuapplication/json. - Utilisez HTTPS même si les filtres d’intent de l’application déclarent aussi
http. - Aucune redirection, ni 301 ni 302.
- Publiez-le sur chaque domaine hôte que gère l’application.
- Un même fichier peut lister plusieurs applications, et le champ
sha256_cert_fingerprintsaccepte plusieurs empreintes, par exemple pour les versions de débogage et de production.
Si vous utilisez Play App Signing, l’empreinte obtenue avec keytool sur votre poste ne correspondra généralement pas à celle des appareils des utilisateurs. Google indique de prendre le bon extrait JSON dans la Play Console, sous Release > Setup > App signing.
Côté application, il s’agit d’un filtre d’intent avec autoVerify. Voici la forme de la documentation 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>
Android vérifie chaque nom d’hôte de ces filtres, et un hôte générique comme *.example.com exige le fichier sur le domaine racine example.com (Android Developers). Sur Android 15 et plus, la vérification s’exécute aussi périodiquement, et une modification du fichier peut prendre jusqu’à sept jours pour se propager ; sur Android 14 et moins, le fichier n’est lu qu’à l’installation ou à la mise à jour (Android Developers).
Liste de contrôle du serveur
Les deux fichiers échouent pour les mêmes quelques raisons, donc vérifiez le serveur une fois pour les deux :
| Contrôle | Pourquoi | Comment tester |
|---|---|---|
| HTTPS | Les deux plateformes l’exigent, et Apple demande un certificat valide | Ouvrez l’URL dans un navigateur |
| Pas de 301 ni de 302 | Les redirections ne sont prises en charge pour aucun des deux fichiers | curl -sI renvoie un 200 |
| iOS : public pour toutes les IP et tous les user agents | Le CDN d’Apple télécharge le fichier, et un pare-feu ou un filtre de bots le bloque | curl -A "MyAgent-Bot/1.0" <url> renvoie le fichier |
Android : Content-Type: application/json |
Google l’indique comme exigence | En-tête de curl -sI |
| Le même fichier sur chaque domaine et sous-domaine listé | Chaque hôte est vérifié séparément | Lancez le contrôle pour chaque hôte |
Pour le type de contenu, servir les deux fichiers en application/json garde la configuration uniforme. La documentation d’Apple n’indique pas de type de contenu pour le fichier iOS, donc ce point relève de votre choix. Un exemple statique pour nginx :
location = /.well-known/apple-app-site-association {
default_type application/json;
}
location = /.well-known/assetlinks.json {
default_type application/json;
}
Comment vérifier que ça fonctionne
Contrôlez le fichier depuis l’extérieur, puis le comportement sur un appareil. Les étapes de débogage d’Apple, tirées de TN3155 :
- Lancez
curl -v https://<domaine>/.well-known/apple-app-site-associationet vérifiez un 200 et le JSON, pas un 301, 302, 403 ou 404. - Sur un Mac,
sudo swcutil dl -d <domaine>vérifie que le fichier se télécharge, etsudo swcutil verify -d <domaine> -j <chemin-du-JSON> -u <URL>vérifie qu’une URL correspond à un motif. - Sur un iPhone, collez le lien dans l’app Notes et restez appuyé dessus. Si tout est bien configuré, les options d’ouverture dans l’application et dans le navigateur apparaissent.
Pour Android, la vérification manuelle de Google sous Android 12 et plus (pour une application ciblant une version antérieure à Android 12, lancez d’abord 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
# attendez quelques minutes, puis :
adb shell pm get-app-links com.example
La sortie liste chaque domaine avec un état comme verified ou legacy_failure. Google propose aussi un générateur et un testeur de listes de déclarations (outil Digital Asset Links) pour tester un fichier de déclarations existant. Pour une routine de test plus large, voir la liste de contrôle des tests de site mobile.
Quand les liens n’ouvrent pas l’application
Taper une URL dans la barre d’adresse du navigateur n’ouvre jamais l’application sur iOS, car c’est une navigation directe dans le navigateur ; si l’utilisateur est déjà sur votre domaine, un lien vers le même domaine reste aussi dans Safari (TN3155). La solution d’Apple pour des parcours comme un bouton de connexion est un autre sous-domaine, avec sa propre entrée applinks et son propre fichier AASA, pour que le système traite le toucher comme une sortie du site.
Les navigateurs intégrés aux applications demandent des tests séparés. Apple indique que les liens touchés dans une application de navigation ou dans un WKWebView peuvent ouvrir votre application, mais précise aussi que les navigateurs tiers décident d’activer ou non les universal links (« Les universal links peuvent ne pas être activés dans tous les navigateurs web », selon TN3155), et qu’une application qui ouvre votre lien par son propre appel open(_:) n’ouvrira pas le sien en retour (Apple). La documentation de la plateforme ne dit pas si le navigateur intégré d’une application sociale donnée transmet le lien à votre application ; testez donc celles qui vous importent sur un vrai téléphone.
Bannière d’application intelligente en solution de repli
Une bannière d’application intelligente est une invite réservée à iOS sur la page web : une balise meta dans le <head> de chaque page où vous la voulez. Selon Apple, elle ouvre l’application si elle est installée et renvoie vers l’App Store sinon.
<meta name="apple-itunes-app" content="app-id=myAppStoreID, app-argument=https://example.com/buy/42">
app-id est obligatoire, et l’app-argument facultatif transmet une URL à l’application pour qu’elle ouvre l’écran correspondant. Apple indique deux limites : les bannières n’apparaissent pas dans une frame, et elles n’apparaissent pas dans le simulateur iOS.
Si vous ne publiez pas d’application native, vous n’avez besoin d’aucun des deux fichiers ; une application web progressive s’installe depuis le navigateur.
Vérifiez la page de repli à la taille d’un mobile
Tous ceux qui n’ont pas l’application, et chaque lien qui ne se transmet pas, arrivent sur votre page web : elle doit donc fonctionner sur téléphone. Mobile View Extension recharge l’onglet avec le user agent, la taille d’écran et le ratio de pixels d’un téléphone, ce qui vous montre la version mobile réelle de la page de repli à plusieurs tailles ; vous pouvez y ajouter l’émulation d’appareil de Chrome. Il ne peut pas tester le transfert vers l’application : il tourne sur Chrome de bureau, n’a pas d’événements tactiles ni d’applications installées. La gestion des liens demande donc un iPhone ou un téléphone Android, ou le simulateur iOS ou l’émulateur Android. Pour iOS sans matériel, voir tester un site web sur un iPhone sans iPhone.
Questions fréquentes
Quelle différence entre universal links et deep links ?
Les deep links forment la catégorie large ; les universal links sont la variante vérifiée d’Apple, bâtie sur des liens HTTP ou HTTPS standard. Un deep link peut aussi utiliser un schéma d’URL personnalisé, qui n’est pas lié à un site web que vous contrôlez. Les App Links Android sont la forme vérifiée sur Android, qui ajoute le contrôle Digital Asset Links aux deep links ordinaires.
Où placer apple-app-site-association ?
À https://<domaine>/.well-known/apple-app-site-association, sans extension de fichier, servi en HTTPS avec un certificat valide et sans redirection. Chaque sous-domaine listé par l’application a besoin de sa propre copie.
Pourquoi mon universal link ouvre-t-il Safari au lieu de l’application ?
Les causes fréquentes sont une redirection, un 403 ou un 404 sur le fichier, une entrée de sous-domaine manquante ou un toucher vers le même domaine. Apple les énumère dans TN3155 ; taper l’URL dans la barre d’adresse, ou toucher un lien vers le même domaine pendant la navigation dans Safari, garde l’utilisateur dans le navigateur. Vérifiez d’abord le fichier avec curl -v.
Faut-il les deux fichiers ?
Vous avez besoin du fichier de chaque plateforme pour laquelle vous publiez une application. Un site qui a une application iOS et une application Android sert les deux, et chacun est indépendant de l’autre.