Chrome dice a ogni server che il tuo telefono ha Android 10
Dal 2023 Chrome su Android invia lo stesso user agent da qualsiasi telefono: Android 10, modello K. Cosa ha comportato per il matching dei deferred deep link, perché non l’abbiamo risolto con Critical-CH e come i domini dei link di Appy ora recuperano la versione e il modello reali. In più, lo stesso problema nella versione iOS 26.
Ormai ogni telefono Android è un «K»
Prendi un Pixel con l’ultima versione di Android e un Galaxy di quattro anni fa. Apri la stessa pagina in Chrome su entrambi. A parte la versione di Chrome, l’header User-Agent che inviano è identico: Android 10, modello del dispositivo K.
Non è un bug. È la riduzione dello user agent (user-agent reduction), una modifica di Chrome a tutela della privacy che ha congelato le parti della stringa utili a fare il fingerprinting di un dispositivo. Su Android è arrivata con Chrome 110. Secondo la cronologia del progetto Chromium, il rilascio è iniziato il 7 febbraio 2023 e ha raggiunto tutti i client Android l’11 maggio 2023.
La maggior parte dei siti non se n’è nemmeno accorta. Chi associava installazioni di app e clic, invece, sì.
Lo stesso header, prima e dopo
Prima di Chrome 110
Mozilla/5.0 (Linux; Android 9; SM-A205U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36Da Chrome 110 in poi
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36Cosa si è rotto nei deferred deep link
Un deferred deep link deve sopravvivere a un’installazione. Quando lo store può trasportare un token, lo fa: Google Play e Huawei AppGallery passano entrambi un install referrer alla nuova app, e la corrispondenza è esatta. Quando non può, perché l’installazione è partita da una ricerca nello store, da un sideload o da uno store senza referrer, non resta che una stima: trovare un clic recente dalla stessa rete e chiedersi se sembra lo stesso telefono.
Quel «sembra» si basava sullo user agent. Un clic da Android 14 era un candidato poco credibile per un telefono che al primo avvio dichiara Android 15, e un clic da un Galaxy lo era per un Pixel. Dopo la riduzione, ogni clic da Chrome diceva Android 10 e K. La versione non restringeva più il campo, e su una rete affollata, in un ufficio o in un campus, ogni telefono Android dell’edificio sembrava uguale a tutti gli altri.
Appy legge Android 10; K per quello che è: niente versione, niente modello. Senza nient’altro nel clic, tutti i clic Android dalla stessa rete sembravano uguali, e Appy non riusciva a distinguere il telefono del tuo nuovo utente dagli altri.
La soluzione da manuale conta ogni clic due volte
Chrome non ha cancellato l’informazione: l’ha spostata negli User-Agent Client Hints. Alcuni hint a bassa entropia arrivano con ogni richiesta: marca e versione major del browser, se il dispositivo è mobile e il nome della piattaforma. I due che contano qui, Sec-CH-UA-Platform-Version e Sec-CH-UA-Model, sono ad alta entropia. Chrome li invia solo dopo che il sito li ha chiesti con un header di risposta Accept-CH, quindi la prima richiesta a un sito non li contiene mai.
Per i dati che servono a una pagina fin dal primissimo caricamento, la guida di Google Privacy Sandbox sulla riduzione su Android (27 febbraio 2023) rimanda a Critical-CH. Il server indica gli hint senza i quali non può lavorare; Chrome si accorge che mancavano, scarta la risposta e invia di nuovo la richiesta, questa volta con gli hint.
Il problema sta tutto in quel «di nuovo». Per un servizio di redirect, quel secondo tentativo è una seconda navigazione verso lo stesso link: ogni tap su Android verrebbe contato due volte e lascerebbe due record di clic. Preferiamo lavorare un po’ di più piuttosto che mettere numeri sbagliati nella dashboard di ogni cliente, per questo Appy non usa Critical-CH.
Cosa fanno invece i domini dei link di Appy
Due meccanismi: uno per il primo tap da un browser, uno per tutti i tap successivi.
Chrome sul telefono
acme.appy.to
- 01Primo tap su un link
GET /spring HTTP/2 Host: acme.appy.to User-Agent: Mozilla/5.0 (Linux; Android 10; K) … Chrome/154.0.0.0 Mobile Safari/537.36 Sec-CH-UA-Mobile: ?1 Sec-CH-UA-Platform: "Android"Solo hint a bassa entropia. Lo user agent dice Android 10, modello K.
- 02Pagina intermedia
HTTP/2 200 Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Model Content-Type: text/html; charset=utf-8La pagina che apre l’app o lo store. Con Accept-CH chiede entrambi gli hint in ogni richiesta successiva.
- 03Prima del passaggio
const hints = await navigator.userAgentData .getHighEntropyValues(["platformVersion", "model"]) → {platformVersion: "16.0.0", model: "Pixel 9", …} navigator.sendBeacon(…)La pagina legge i valori reali, li aggiunge al record di questo clic e poi passa la mano.
- 04Ogni tap successivo
GET /summer HTTP/2 Host: acme.appy.to Sec-CH-UA-Platform-Version: "16.0.0" Sec-CH-UA-Model: "Pixel 9"Chrome ricorda la richiesta per questa origine finché l’utente non cancella i dati del sito, quindi ora gli hint viaggiano come header. Niente script, niente secondo tentativo.
Cosa cambiano versione e modello reali
Con la versione e il modello reali nel clic, clic e telefono devono coincidere su entrambi. L’SDK comunica il modello del telefono da Build.MODEL al primo avvio dell’app, quindi i due si possono confrontare. Un clic da un Pixel 9 non può più essere scambiato per un’installazione su un Galaxy, e un clic da Android 15 non va più bene per un telefono con Android 16.
La differenza si vede soprattutto sulle reti affollate. Sulla rete di un ufficio con quaranta telefoni, i clic degli altri modelli vengono scartati, e spesso resta solo quello del Pixel.
Tutto questo riguarda le installazioni che arrivano senza token. Su Android, gli install referrer di Google Play e AppGallery risolvono ancora per primi la maggior parte delle installazioni; i Client Hints servono per il resto. Senza referrer né click ID, Appy non può verificare l’installazione: con l’attribuzione rigorosa attiva risulta organica, anche se il clic corrisponde perfettamente.
Una rete d’ufficio, prima e dopo
Un Pixel 9 su una rete d’ufficio affollata apre l’app per la prima volta, quattro minuti dopo che il proprietario ha toccato un link. Aveva chiuso la pagina dello store aperta dal link e poi installato l’app cercandola nel Play Store, quindi non arriva nessun referrer.
Anche iOS ha congelato il suo numero
Safari ci è arrivato per un’altra strada. Secondo le note di rilascio di Safari 26.0 pubblicate da Apple, su iOS 26 e iPadOS 26 Safari ora riporta nel suo user agent una versione dell’OS congelata: l’ultima rilasciata prima di iOS 26. In pratica un iPhone con iOS 26 si presenta come «iPhone OS 18_6». Il token Version/26.0, più avanti nella stringa, segue ancora la versione di Safari.
Safari non supporta gli User-Agent Client Hints, quindi non c’è niente da chiedere. Appy lo gestisce nel matching: se il telefono ha iOS 26 o successivo, un clic che dice iOS 18.6 viene letto come «26 o successivo», non come una versione esatta, perché Safari non dice più quale sia.
Se le installazioni le associ tu
Niente di tutto questo vale solo per Appy.
Tratta «Android 10; K» come sconosciuto
Individualo e mettilo da parte. Un valore congelato che sembra un dato fa più danni di un campo vuoto.
Chiedi gli hint dal dominio che gestisce il clic
Invia Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Model dal tuo dominio dei link e leggi navigator.userAgentData alla prima visita, quando gli header non possono ancora esserci.
Prima di aggiungere Critical-CH, calcola l’effetto del secondo tentativo
Una navigazione ripetuta è una seconda richiesta. Se conti le richieste, deduplicale oppure rinuncia al secondo tentativo.
Leggi iOS 18.6 come «26 o successivo»
Non scartare un’installazione iOS 26 perché il suo clic diceva 18.6. Trattala come iOS 26 o successivo, non come una versione esatta.
Meglio i token delle stime
Install referrer e click ID battono qualsiasi user agent. Ricorri a una stima solo quando non è arrivato nulla di deterministico, e dichiara che è una stima.
Leggi anche
Domande frequenti
Perché Chrome dice Android 10 su qualsiasi telefono?
Per la riduzione dello user agent. Da Chrome 110, distribuito tra febbraio e maggio 2023, Chrome su Android congela nella stringa User-Agent la versione dell’OS a 10 e il modello del dispositivo a K. I valori reali sono disponibili tramite gli User-Agent Client Hints.
Come ottengo la versione reale di Android in Chrome?
Chiedi l’hint Sec-CH-UA-Platform-Version con un header di risposta Accept-CH, oppure chiama navigator.userAgentData.getHighEntropyValues(["platformVersion"]) nella pagina. L’header arriva solo nelle richieste fatte dopo che Chrome ha visto il tuo Accept-CH.
Critical-CH risolve il problema della prima richiesta?
Ti procura gli hint facendo ripetere la richiesta a Chrome. Per le pagine normali funziona. Per tutto ciò che conta le richieste, come i redirect o il tracciamento dei clic, la ripetizione sembra una seconda visita, a meno che tu non la deduplichi.
Cosa riporta Safari su iOS 26?
Una versione dell’OS congelata. Su iOS 26 e iPadOS 26 Safari riporta l’ultima versione rilasciata prima di iOS 26, in pratica 18_6, mentre il token Version/26 segue ancora Safari. Safari non supporta gli User-Agent Client Hints.
Anche le WebView Android e i browser in-app hanno lo user agent ridotto?
Per impostazione predefinita non ancora. Google ha detto che lo user agent predefinito di WebView riceverà lo stesso trattamento a partire da Android 17, e le app che impostano un proprio user agent lo mantengono.
Continua a esplorare
Deferred deep linking senza SDK: come funziona davvero sotto il cofano
Puoi portare il contesto di un link oltre l’installazione senza incorporare un SDK di attribution. Ecco cosa sopravvive davvero al confine dello store su Android e iOS, cosa si rompe e quanto costa in privacy ogni scorciatoia.
Scopri quale link ha portato ogni installazione: l’SDK iOS e Android di Appy
Ora Appy segue i tuoi link anche oltre lo store. Il nuovo SDK ti mostra installazioni, eventi in-app e ricavi per ogni link, QR code e campagna, e apre ai nuovi utenti la schermata giusta.
Deferred deep linking: come funziona e quando usarlo
Porta l’intento originale del link oltre l’installazione, così i nuovi utenti arrivano sulla schermata giusta in-app invece che su una home generica.
Cerchi altro? Sfoglia tutti gli argomenti su il blog.
Associa le installazioni in base alle prove, non ad «Android 10»
I domini dei link di Appy ora chiedono i Client Hints. Deferred deep linking e attribuzione delle installazioni arrivano con l’SDK nel piano Enterprise, e con gli smart link si parte gratis.