
Kan een QR-code direct een app openen? Universal Links en App Links uitgelegd
Waarom een QR-scan niet altijd een app opent, ook al staat hij geïnstalleerd. Alles over Universal Links, App Links, assetlinks.json en deferred deep linking voor bureaus.
ScanKit · Organization
· 21 min. leestijd
Kan een QR-code direct een app openen? Universal Links, App Links en waarom de meeste scans toch in de browser landen
Een bureau draait een loyaliteitscampagne voor een retailklant. De app staat al op de telefoon van de klant, er staan punten op, en de QR-code op het kassabonnetje moet de app direct openen op het scherm "scan om te sparen". In plaats daarvan opent de telefoon Safari of Chrome en verschijnt een gewone webpagina: het hele idee van de campagne, de interactie binnen de app houden die de klant heeft laten bouwen, verdampt in één scan. Dit is geen kapotte QR-code. Het is een mismatch tussen wat een QR-code daadwerkelijk doet (een URL coderen) en wat "een app openen" vereist (een keten van OS-vertrouwen en -resolutie waar een camerascan niet automatisch aan meedoet). Dit artikel behandelt het mechanisme grondig: wat Universal Links en App Links zijn, waarom ze niet gegarandeerd afgaan alleen omdat iemand scande in plaats van tikte, wat deferred deep linking toevoegt voor mensen die de app nog niet hebben, en de concrete lijst met dingen die de keten breken, zodat een bureau een "waarom komt dit in de browser terecht"-ticket kan diagnosticeren en oplossen in plaats van gokken. Dit is een ander probleem dan nieuwe installaties naar de juiste appstore leiden, wat behandeld wordt in één QR-code voor beide appstores; dit artikel gaat over mensen die de app al hebben geïnstalleerd, of die de winkelbezoek en het eerste scherm van de app naadloos aan elkaar geknoopt willen zien.
Wat "deep linking" precies betekent, en de drie mechanismen erachter
Een deep link is een URL die, in plaats van een generiek beginscherm te openen, de gebruiker naar een specifiek stuk content in een app brengt: een productpagina, een loyaliteitssaldo, een evenemententicket. Er bestaan drie mechanismen om dat voor elkaar te krijgen, en ze zijn niet onderling uitwisselbaar.
Universal Links (iOS)
Universal Links zijn gewone https://-URL's. Er is geen speciaal schema; de truc zit in een klein JSON-bestand, het apple-app-site-association (AASA) bestand, gehost op /.well-known/apple-app-site-association op het bestemmingsdomein, gecombineerd met een entitlement die binnen de app zelf is gedeclareerd. Apple omschrijft het zelf als: "je app neemt een entitlement over... en je webserver neemt één JSON-bestand over." Omdat alleen de eigenaar van het domein dat bestand kan publiceren, kan geen enkele andere app beweren links af te handelen voor een domein dat hij niet beheert, en precies die zwakte moesten Universal Links dichten.
Sinds iOS 14 halen apparaten het AASA-bestand niet meer bij elke controle rechtstreeks van je server op. Ze halen het op via een door Apple beheerd content delivery network, met een aparte "alternate mode" beschikbaar voor interne of ontwikkeldomeinen die die cache moeten overslaan. Dat detail is operationeel relevant: een net geüpload AASA-bestand is niet per se meteen van kracht, omdat de CDN nog moet bijtrekken.
iOS onthoudt ook de eerdere keuze van een gebruiker. Als iemand eerder heeft gekozen om de content van een domein in Safari te bekijken in plaats van in de bijbehorende app (door lang op een link te drukken of de app te verlaten), neigt het systeem ernaar diezelfde keuze voor dat domein te herhalen totdat de gebruiker bewust opnieuw met de app in aanraking komt, meestal door nogmaals op een Smart App Banner te tikken.
Smart App Banners, een verwant maar apart mechanisme
Een Smart App Banner is de balk die bovenin Safari verschijnt, gedeclareerd met één meta-tag in de head van de pagina (apple-itunes-app). Als de app is geïnstalleerd, opent tikken op de banner hem direct; zo niet, dan leidt het naar de App Store-vermelding. Het gaat alleen af wanneer Safari zelf de getagde pagina rendert en iemand met de banner interacteert, niet in een in-app browser zoals die van Instagram of TikTok, en niet automatisch bij het scannen. Het is een verwant maar apart onderdeel van dezelfde puzzel, en het is goed dit niet te verwarren met echte Universal Link-resolutie.
Android App Links (geverifieerd)
Het Android-equivalent heet App Links, en het woord dat ertoe doet is "geverifieerd". Een intent filter in de app declareert android:autoVerify="true", wat (vanaf Android 6.0 / API 23) ervoor zorgt dat Android bij installatie controleert of de app daadwerkelijk gemachtigd is om links af te handelen voor de hosts die in dat filter worden genoemd. De controle werkt door een Digital Asset Links-bestand op te halen bij https://jouwdomein.nl/.well-known/assetlinks.json, een manifest dat "openbaar verklaart welke apps gemachtigd zijn om links voor je domein af te handelen." Pas als dat bestand correct wordt opgelost, behandelt Android de app als de geverifieerde handler voor dat domein, in plaats van de gebruiker een keuzedialoog voor te schotelen of gewoon een browser te openen.
Custom URL-schema's: de oudere, zwakkere optie
Voordat Universal Links en App Links bestonden, registreerden apps hun eigen schema, iets als myapp://. Die schema-aanpak heeft twee structurele problemen die geen van beide platformen ooit volledig heeft opgelost. Ten eerste is er geen betrouwbare manier om vooraf te detecteren of de doel-app is geïnstalleerd. Is dat niet het geval, dan levert tikken op de link niets op (een stille doodlopende weg sinds iOS 9.2, zonder ingebouwde terugval naar een website of winkelvermelding). Ten tweede kon historisch elke app elk schema-tekst registreren, waardoor twee verschillende apps hetzelfde konden claimen zonder enig eigendomsbewijs, precies de dubbelzinnigheid die Universal Links en App Links moesten wegnemen door de link in plaats daarvan aan een geverifieerd webdomein te koppelen. Custom schema's duiken nog steeds op als terugvallaag binnen sommige attributie-SDK's, maar ze zijn niet het primaire mechanisme waarop een bureau in 2026 moet vertrouwen.
Waarom een QR-scan zich niet gedraagt als een gewone tik
Dit is het punt waar bureaus over struikelen, en het verdient precisie in plaats van een schouderophalen. Universal Links en App Links zijn ontworpen om te activeren wanneer het besturingssysteem zelf een tik op een kwalificerende HTTPS-link afhandelt. Een QR-scan doorloopt dat pad niet automatisch. Wat er gebeurt, hangt af van welke app de scan uitvoerde en wat die met de gedecodeerde URL deed.
Op een ontwikkelaarsforum stelde iemand precies de vraag die een bureau zich vóór een campagne zou moeten stellen: roept een QR-code die een Universal Link codeert de app daadwerkelijk aan wanneer die met de Camera-app wordt gescand? Het eigen antwoord, na testen, was dat het werkte voor hun app en domein, maar noch Apple noch iemand officieel bevestigde het onderliggende mechanisme. Dat is de eerlijke stand van zaken bij deze functie: goed onderbouwd in de praktijk, maar geen gedocumenteerde garantie van Apple of Google. Drie variabelen bepalen de uitkomst in de meeste gemelde gevallen.
Welke app de scan uitvoerde. De native Camera-app op iOS en de native scanner op Android (vaak via Google Lens) geven een gedecodeerde HTTPS-URL doorgaans aan het OS door zoals een aangetikte link zou worden afgehandeld, en daarom lossen Universal Links en App Links via deze apps vaak correct op. Bij een scanner-app van derden is dat niet gegarandeerd; sommige openen de URL in hun eigen in-app browser of webview in plaats van hem aan het systeem door te geven, en een webview heeft niet dezelfde link-resolutierechten als een echte tik op OS-niveau.
Welke browser als standaard is ingesteld. Deep-link-leveranciers documenteren, als bekend en soms onopgelost probleem, dat bepaald terugvalgedrag op iOS alleen betrouwbaar werkt in Safari en spaak loopt in Chrome of andere browsers van derden op hetzelfde toestel. Als iemands standaardbrowser niet Safari is, kan een link die voor de ene gebruiker correct oplost bij een andere, op identieke hardware, stilletjes uitkomen op een gewone webpagina.
Getikt versus geplakt of getypt. Deep-link-platforms waarschuwen expliciet tegen het testen van links door ze in Notities te plakken of rechtstreeks in de adresbalk van een browser te typen, omdat het besturingssysteem dat bewust niet als dezelfde vertrouwenscontext beschouwt als een tik, en de app niet zal openen. Een QR-scan zit in de meeste gevallen dichter bij een tik dan bij plakken, maar de exacte interne afhandeling is niet gepubliceerd, en juist daarom is testen op echte toestellen met de echte scanner die je campagne verwacht (native camera, geen QR-lezer-app) hier belangrijker dan bij de meeste andere functies.
De praktische conclusie: correct geconfigureerde AASA- en assetlinks.json-bestanden zijn noodzakelijk, maar niet voldoende. Een bureau dat een "waarom opent dit de app niet"-ticket krijgt, moet eerst vragen met welke app de klant scande en welke browser standaard staat ingesteld, voordat het aanneemt dat de technische opzet van de campagne kapot is.
Deferred deep linking: mensen doorsturen die de app nog niet hebben
Universal Links en App Links helpen pas zodra de app al is geïnstalleerd. Een apart probleem, waarvoor geen native OS-oplossing bestaat, is iemand zonder de app zover krijgen dat die de app installeert en vervolgens precies op de content landt waarvoor gescand werd, in plaats van op een generiek beginscherm. Dat gat heet deferred deep linking, en het dichten ervan vereist ofwel een attributie-SDK van derden (Branch, AppsFlyer en Adjust zijn de bekende namen) ofwel het zelf bouwen van het equivalent.
Het mechanisme dat deze SDK's gebruiken is een vorm van probabilistische matching, ook wel device snapshotting genoemd. Op het moment dat iemand op de uit de QR-code afgeleide link klikt, legt de server van de leverancier een "browser snapshot" vast: signalen als IP-adres, OS, OS-versie, toestelmodel en schermformaat, met tijdstempel. Nadat de installatie via de appstore is voltooid en de app voor het eerst wordt geopend, neemt de SDK een "device snapshot" van hetzelfde soort signalen en probeert die terug te koppelen aan een recente browser snapshot van hetzelfde toestel. Branch, een van de grotere leveranciers in deze markt, zegt honderden miljoenen van zulke snapshots te gebruiken voor de matching. Het is een redelijke technische aanpak van een echt lastig probleem, maar het is probabilistisch, niet deterministisch. Het kan geen gedeelde identifier aanhalen zoals een login dat kan; het leidt "waarschijnlijk hetzelfde toestel" af uit een cluster van gewone signalen.
Die afleiding zit dicht tegen een beleidslijn aan die het waard is om te kennen voordat een bureau er een campagne op bouwt. Apple's App Store Review Guidelines verbieden het afleiden van data van een toestel specifiek om het te identificeren, in de richtlijnen omschreven als fingerprinting, ongeacht of de gebruiker toestemming heeft gegeven voor tracking onder App Tracking Transparency. Onafhankelijk academisch onderzoek heeft in de praktijk aangetoond dat apps gedeelde, van fingerprints afgeleide identifiers berekenen juist om ATT-restricties te omzeilen, wat mede verklaart waarom de regel in zijn huidige expliciete vorm bestaat. Niets hiervan betekent dat deferred deep linking via een gerenommeerde SDK tegen de regels is; gevestigde leveranciers ontwerpen hun matching om binnen Apple's beleid te blijven en beweren doorgaans niet dat de match deterministisch is. Het betekent wel dat een bureau de door de leverancier gerapporteerde matchpercentages moet zien als een best-effort inschatting, geen garantie, en een gedocumenteerde reden moet hebben (in de privacyverklaring en verwerkersovereenkomst van de klant) om überhaupt een attributie-SDK van derden te gebruiken, zeker bij campagnes gericht op EU-gebruikers. Zie zijn QR-codes AVG-proof voor het bredere plaatje van toestemming en dataverzameling dat een scan in gang kan zetten.
Waar de keten daadwerkelijk breekt
De meeste meldingen van "de app opende niet" zijn terug te voeren op een korte lijst oorzaken, ruwweg gerangschikt naar hoe vaak bureaus ze in de praktijk tegenkomen.
- Verificatie is op Android nooit voltooid. Het
assetlinks.json-bestand ontbreekt, is verkeerd opgemaakt, of staat op het verkeerde pad, of de intent filter heeft nooitautoVerify="true"gedeclareerd. Android valt stilletjes terug op het openen van een browser in plaats van een foutmelding te tonen, waardoor dit een hele campagne lang onopgemerkt kan blijven. - Het AASA-bestand wordt via een redirect geserveerd. Apple's eigen tooling noemt HTTP-redirects op de AASA-response expliciet als niet-ondersteund; het bestand moet rechtstreeks worden geserveerd, met het juiste content-type, als geldige JSON, zonder bestandsextensie, precies op
/.well-known/apple-app-site-association. - CDN-vertraging op iOS. Omdat toestellen sinds iOS 14 het AASA-bestand via Apple's CDN ophalen in plaats van rechtstreeks bij je server, is een net gecorrigeerd bestand niet overal onmiddellijk van kracht; een melding van "gefixt, nog steeds kapot" een uur later kan simpelweg de cache zijn die nog moet bijtrekken.
- De eerdere in-browserkeuze van de gebruiker blijft plakken. Als iemand eerder heeft gekozen om een domein in Safari te blijven bekijken, kan iOS die keuze bij latere bezoeken blijven volgen totdat de gebruiker expliciet opnieuw met de app in aanraking komt.
- De QR-code wijst naar een generiek verkortingsdomein, niet naar het eigen domein van de klant. Universal Links en App Links worden per domein geverifieerd. Als de gecodeerde URL op een shortlink-domein van derden staat zonder eigen AASA- of assetlinks.json-bestand, en zonder relatie tot de app van de klant, is er niets voor beide besturingssystemen om te verifiëren, en wordt het bezoek elke keer afgehandeld als een gewoon webverzoek, hoe goed het eigen domein van de klant ook is geconfigureerd.
- De standaardbrowser is geen Safari, of de scan kwam van een scanner-app van derden. Zoals hierboven: dit verandert in welke vertrouwenscontext de tik terechtkomt, en het is de moeite waard dit uit te sluiten voordat een configuratiefout wordt aangenomen.
Een QR-code zo instellen dat deep linking de beste kans krijgt
Geen van de bovenstaande mechanismen zit in de QR-code zelf. Een QR-code codeert alleen een URL; al het gedrag dat hier beschreven wordt, komt voort uit wat er achter die URL zit en hoe de app is geconfigureerd. Dat heeft twee praktische gevolgen voor hoe een bureau de campagne moet bouwen.
Richt de code op een domein dat de klant daadwerkelijk bezit en beheert, idealiter hetzelfde domein waarvoor de AASA- en assetlinks.json-bestanden van de app al zijn geconfigureerd, in plaats van een generieke shortener. Dit is de meest voorkomende reden waarom deep linking stilletjes faalt bij een verder correct geconfigureerde app: de QR-code gaf geen van beide besturingssystemen ooit een domein om te verifiëren.
Gebruik een dynamische QR-code zodat de bestemmings-URL kan worden gecorrigeerd zonder herdruk als achteraf blijkt dat de verificatie verkeerd is geconfigureerd nadat de oplage al is verstuurd, behandeld in dynamische versus statische QR-codes. Een typefout in assetlinks.json ontdekken nadat er tienduizend kassabonnen zijn gedrukt, is een veel kleiner probleem als de oplossing een redirect-update is in plaats van een herdruk.
Bepaal eerlijk of de campagne deferred deep linking überhaupt nodig heeft. Als het doel simpelweg is om een nieuwe gebruiker naar de juiste appstore-vermelding te leiden, is gewone toestel-gebaseerde doorverwijzing (de User-Agent-header uitlezen en iOS naar de App Store, Android naar Google Play sturen) eenvoudiger, kent geen fingerprinting-risico, en is de aanpak die behandeld wordt in één QR-code voor beide appstores. Grijp pas naar een volwaardige deferred deep linking-SDK wanneer de campagne er echt van afhangt dat een gloednieuwe installatie direct op specifieke content landt (een bepaalde loyaliteitsactie, een specifieke evenementpagina) in plaats van simpelweg het beginscherm van de app, want alleen in dat scenario levert de extra complexiteit, kosten en privacyrisico daadwerkelijk iets op.
Test met het echte scanpad dat de campagne in de praktijk zal zien, dus de native Camera-app op een fysiek toestel, geen QR-lezer-app op een bureau, en geen geplakte link. Gezien hoezeer dit mechanisme afhangt van welke app de scan uitvoert, loopt testen met iets anders het risico een opzet te bevestigen die voor een aanzienlijk deel van de echte klanten faalt.

Waar dit terugkomt in echte campagnes
Loyaliteitsinschrijving via retailverpakking. Een QR-code op verpakking stuurt een bestaande klant rechtstreeks naar het loyaliteitsonderdeel van een app die die al heeft, en een first-time scanner naar eerst de winkelvermelding en dan inschrijving.
Evenementenbadges en stand-QR-codes. Een bezoeker die de evenementen-app al heeft geïnstalleerd, wordt doorgestuurd naar zijn sessieschema of de pagina van een specifieke sponsorstand in plaats van naar een generieke evenementenwebsite, terwijl een eerste bezoeker eerst in de store terechtkomt.
Restaurantloyaliteit op kassabonnen. Een QR-code op een kassabon stuurt een bestaande app-gebruiker rechtstreeks naar een bevestigingsscherm voor het sparen van punten voor dat bezoek, wat alleen werkt als de QR-code op de bon naar hetzelfde geverifieerde domein wijst dat de deep-linkconfiguratie van de app al vertrouwt.
Out-of-home promotiecodes. Een QR-code op een poster of een advertentie in het openbaar vervoer, bedoeld om mensen naar een specifiek promotiescherm in een app te sturen, leunt het zwaarst op deferred deep linking, omdat het publiek grotendeels bestaat uit mensen die de app voor het eerst tegenkomen via een publieke, niet-toegeschreven plaatsing, precies het scenario waarvoor attributie-SDK's van derden zoals Branch en AppsFlyer zijn gebouwd.
Veelgestelde vragen
Kan een QR-code direct een app openen in plaats van een browser?
Ja, als de app al is geïnstalleerd en het bestemmingsdomein correct is geconfigureerd met een apple-app-site-association-bestand (iOS) of een geverifieerd assetlinks.json-bestand (Android). De QR-code zelf bevat geen logica; hij codeert alleen een URL, en of die URL de app of een browser opent, wordt bepaald door de configuratie op OS-niveau erachter en, minder voorspelbaar, door welke scanner-app en browser iemand gebruikte.
Waarom opende mijn QR-code een browser terwijl de app is geïnstalleerd en Universal Links zijn ingesteld?
De meest voorkomende oorzaken: de scan kwam van een scanner-app van derden of een in-app browser in plaats van de native Camera-app, de standaardbrowser van de persoon is geen Safari, de bestemmings-URL stond op een generiek verkortingsdomein in plaats van het eigen geverifieerde domein van de klant, of iOS volgt een eerdere "altijd in Safari openen"-keuze voor dat domein. Correct geconfigureerde verificatiebestanden zijn noodzakelijk, maar op zichzelf niet voldoende.
Wat is het verschil tussen een Universal Link en een deep link?
Een deep link is het algemene concept: een URL die specifieke content in een app opent in plaats van het beginscherm. Een Universal Link is Apple's specifieke, geverifieerde implementatie van dat concept voor iOS, met gewone HTTPS-URL's plus een apple-app-site-association-bestand. Het Android-equivalent heet een App Link. Custom URL-schema's zijn een oudere, ongeverifieerde manier om hetzelfde algemene idee te bouwen, met zwakkere garanties.
Heb ik een dienst zoals Branch of AppsFlyer nodig om QR-code deep linking te laten werken?
Niet als iedereen die scant de app al heeft geïnstalleerd en je eigen domein correct is geconfigureerd met Universal Links en App Links; de native OS-mechanismen handelen dat geval zonder SDK van derden af. Een specifieke attributie-SDK wordt zijn kosten waard specifiek voor deferred deep linking, dus het rechtstreeks doorsturen van een gloednieuwe installatie naar specifieke content in plaats van naar het beginscherm van de app, iets waarvoor geen native OS-equivalent bestaat.
Volgt deferred deep linking mensen zonder toestemming?
De matchingtechnieken die deze SDK's gebruiken zijn probabilistisch (gebaseerd op signalen als IP-adres, toestelmodel en OS-versie, niet op een gedeelde login-identifier), en Apple's App Store-richtlijnen verbieden expliciet het gebruik van zulke signalen om een toestel te fingerprinten met het oog op identificatie, ongeacht de toestemmingsstatus onder App Tracking Transparency. Gerenommeerde leveranciers ontwerpen hun matching om binnen dat beleid te blijven, maar een bureau dat er een inzet, moet de juridische grondslag daarvoor documenteren in de privacyverklaring van de klant, vooral bij een EU-publiek, in plaats van dit automatisch als toestemmingsvrij te beschouwen.
Kunnen Android- en iOS-QR-deeplinks dezelfde URL gebruiken?
Ja. Beide platformen controleren onafhankelijk van elkaar hetzelfde bestemmingsdomein, iOS via het apple-app-site-association-bestand, Android via assetlinks.json, dus één QR-code en één bestemmings-URL kunnen op beide platformen correct deep-linkgedrag activeren, zolang beide verificatiebestanden correct op dat domein worden gehost.
Waarom werkt dezelfde QR-code voor de ene klant wel en voor de andere niet?
Omdat de uitkomst afhangt van variabelen die specifiek zijn voor de telefoon van elke klant, niet alleen van de configuratie van de campagne: met welke app iemand scande, welke browser standaard staat ingesteld, of iemand eerder heeft gekozen dat domein in een browser te bekijken in plaats van in de app, en of de linkverificatie van het OS al is doorgedrongen op zijn toestel. Twee mensen die dezelfde code op dezelfde dag scannen, kunnen verschillende resultaten krijgen.
Hoe test ik of mijn QR-code de app correct opent?
Test op een fysiek toestel met de native Camera-app, want dat komt het dichtst bij hoe de meeste echte klanten zullen scannen, in plaats van een QR-lezer op de computer of een geplakte link, die besturingssystemen bewust anders behandelen dan een tik. Test zowel op een toestel waar de app al is geïnstalleerd als op een toestel waar dat niet zo is, en controleer het resultaat zowel met Safari als standaardbrowser als met een andere standaardbrowser op iOS.
De korte versie
Een QR-code codeert altijd alleen een URL; of die URL direct een app opent of in een browser landt, wordt bepaald door verificatiebestanden (apple-app-site-association op iOS, assetlinks.json op Android) die op het bestemmingsdomein worden gehost, door of het OS de scan als een echte tik behandelt, en, voor mensen die de app nog niet hebben, door of er op de achtergrond een deferred deep linking-SDK aan probabilistische matching doet. Richt de QR-code op een domein dat de klant daadwerkelijk beheert, niet op een generieke shortener, gebruik een dynamische QR-code zodat een verkeerd geconfigureerd verificatiebestand kan worden gerepareerd zonder herdruk, en test met de echte Camera-app op een echt toestel voordat de oplage wordt verstuurd. Als het doel alleen is om nieuwe gebruikers naar de juiste appstore te leiden, volstaat de eenvoudigere toestel-gebaseerde doorverwijzing uit één QR-code voor beide appstores prima, zonder de extra complexiteit van deferred deep linking.
Verder lezen

· 18 min. leestijd
QR-codes op direct mail: personaliseren, tracken en de USPS-korting van 2026
Hoe bureaus unieke QR-codes genereren per ontvanger, een mailcampagne betrouwbaar tracken, en wat de USPS-promotie van 2026 echt vereist voor portokorting.
Lees meer
· 18 min. leestijd
UTM-parameters op QR-codes: waarom scans in GA4 als Direct verdwijnen
Zonder UTM-parameters belandt elke gescande QR-code in GA4 als Direct-verkeer. Deze gids laat zien hoe je een naamconventie bouwt die meerdere klanten overleeft, en hoe je voorkomt dat UTM-tags je QR-code te dicht maken om betrouwbaar te scannen.
Lees meer