Link tracking not working on mobile: where iOS 17, Safari and in-app browsers lose the click
Mobile clicks missing from reports? Check in-app browsers, Safari's 7-day cookie cap, iOS 17 parameter stripping and blank referrers, then fix each one.
Muzahid Maruf, FounderUpdated
On this page
- 01Why link tracking is not working on mobile
- 02In-app browsers keep their own storage
- 03Safari deletes cookies that JavaScript writes
- 04iOS 17 removes some parameters before your server sees them
- 05Blank referrers, app links and preview fetches
- 06Test your own links on real phones
- 07Size the gap before you rebuild anything
- 08Write the visitor ID onto the payment
- 09What TrackRev does about this
Explore with AI
Opens this article inside the chosen assistant with a ready-made prompt.
Link tracking not working on mobile usually traces to one of 5 causes: an in-app browser such as Instagram or Facebook, a Safari cookie capped at 7 days, a parameter that iOS 17 Link Tracking Protection removed, an app that sent no referrer, or an Android App Link or iOS universal link that opened your app instead of your page.
Each leaves the same trace: mobile clicks climb while signups stay flat or arrive as Direct.
Key takeaways
- Mobile attribution breaks in 5 places: in-app browsers, Safari's 7-day cookie cap, iOS 17 parameter removal, blank referrers and app links that open your app.
- Safari ITP caps cookies written by JavaScript at 7 days, or 1 day after a classified tracker links to a URL with a query string, and a click logged on your own server escapes both.
- Apple named no parameters when it announced the iOS 17 feature on June 5, 2023, so test which tags reach your server from an iPhone.
- Safari 26.0, released September 15, 2025, hides query parameters and document.referrer from scripts it classifies as fingerprinting.
- If iPhone clicks on a link convert far below Android clicks, such as 2.0% against 5.0%, the gap points at loss on the Apple side.
- TrackRev logs each click on the server, and its pixel cookie lasts 7 days on Safari, so link a visitor to an email or a Stripe payment ID within a week.
Why link tracking is not working on mobile
| What you see | Likely cause | What fixes it |
|---|---|---|
| Many clicks, few signups from Instagram or Facebook | An in-app browser with separate storage | Log the click at a redirect |
| Direct signups 8 or more days after a click | Safari's 7-day cookie cap | Keep the visitor ID on the server |
| No UTM tags or gclid on iPhone | iOS 17 Link Tracking Protection in Safari 17.0 | Put the source in the link path |
| Social clicks with no Referer | App browsers that send none | 1 link per channel |
| A click, then no page view | Universal link or Android App Link | Pass the click ID into the app |
| iPhone converts far below Android, such as 2.0% against 5.0% | Loss on the Apple side | Fix the Apple-side rows above |
| Clicks that no person made | Link previews and prefetches | Flag bots, still redirect |
In-app browsers keep their own storage
| Browser | What is documented | Source |
|---|---|---|
| SFSafariViewController on iOS | Apple says an app cannot access its website data and points to ASWebAuthenticationSession for sharing data with Safari | Apple Developer Documentation |
| Instagram and Facebook on iOS | Custom in-app browsers, not SFSafariViewController | Felix Krause, August 10, 2022 |
| WebView on Android | Does not share state with the browser | Chrome Custom Tabs documentation |
| Chrome Custom Tabs on Android | Shares the browser's cookie jar | Chrome Custom Tabs documentation |
I would not trust a published list of which apps keep cookies, since each app can change its browser in any release, so run the test below.
The open-source Matomo Device Detector lists the User-Agent patterns apps use, and this regex applies them at the redirect.
// Tokens from Matomo Device Detector. Apps change them between releases, so confirm with a click from your own phone.// Facebook: FBAN/, FBAV or MetaIAB | Instagram: Instagram + version | LinkedIn: LinkedIn, LinkedInApp// TikTok: TikTok, musical_ly_, com.zhiliaoapp.musically | Snapchat: Snapchat/ + versionconst IN_APP = /FBAN|FBAV|MetaIAB|Instagram|LinkedIn|TikTok|musical_ly|Snapchat/i; app.get("/:code", async (req, res) => { const inApp = IN_APP.test(req.get("user-agent") || ""); // store inApp on the click row so reports can split in-app traffic from Safari and Chrome // ...then log the click and redirect as usual});Safari deletes cookies that JavaScript writes
| Rule | Date | What it limits | What it leaves alone |
|---|---|---|---|
| Intelligent Tracking Prevention 2.1 | February 21, 2019 (Safari 12.1 and iOS 12.2 betas) | Cookies from document.cookie expire in 7 days | Cookies set in an HTTP response |
| Intelligent Tracking Prevention 2.2 | April 24, 2019 (iOS 12.3 and macOS 10.14.5 betas) | The same cookies expire in 1 day after a classified tracker links to a URL with a query string or fragment | Cookies set in an HTTP response |
| Script-writeable storage cap | Current WebKit page | IndexedDB, LocalStorage, SessionStorage and Service Worker data deleted after 7 days without interaction | Home Screen web apps |
| Advanced Fingerprinting Protection | September 15, 2025 (Safari 26.0) | Known fingerprinting scripts cannot set long-lived cookies or LocalStorage, or read query parameters and document.referrer | Scripts Safari does not classify as fingerprinting |
| CNAME and IP cloaking defense | Current WebKit page | Response cookies capped at 7 days when cloaking is detected | Other response cookies |
| Signs up | Days after click | Script cookie | After a tracker link | Click row |
|---|---|---|---|---|
| Wednesday, October 7 | 2 | Present | Gone | Present |
| Sunday, October 11 | 6 | Present | Gone | Present |
| Tuesday, October 13 | 8 | Gone | Gone | Present |
| Monday, October 19 | 14 | Gone | Gone | Present |
| Monday, November 2 | 28 | Gone | Gone | Present |
| Monday, December 7 | 63 | Gone | Gone | Present |
An invented visitor who clicks on Monday, October 5, 2026 and visits once. Tracker column: a classified tracker sent the click.
A signup on October 13 traces back only if an ID in the URL, an email captured earlier or a visitor ID on the payment connects it to the click row.
A script that rewrites its cookie on each page view restarts the 7 days.
ITP is a WebKit feature, so Google Chrome on Android applies none of it, and Google's update of April 22, 2025 kept third-party cookies a choice in Chrome's settings.
iOS 17 removes some parameters before your server sees them
Apple announced Link Tracking Protection on June 5, 2023 for links in Messages, Mail and Safari Private Browsing, and shipped it in Safari 17.0 on September 18, 2023. Apple names no parameters.
Stape's update of August 6, 2025 says gclid and fbclid may be stripped in Private Browsing, Mail and Messages, while Private Browsing keeps utm_ tags.
The click still arrives, and a source in the path of a link you own, such as go.example.com/spring-launch, reaches your server whatever happens to the query string. The iOS 17 Link Tracking Protection post tests each place a link opens.
Blank referrers, app links and preview fetches
Google Analytics 4 files a visit under (direct) / (none) when a redirect or URL shortener strips its source, Google's help page says.
Many app browsers send no Referer either, so TrackRev's Smart Links, which infer a channel from it, record such clicks as Direct.
A link per channel with utm_source and utm_medium set at the redirect avoids that, and the post on GA4 not showing revenue by channel covers the reporting.
A link whose domain is tied to your app can skip the browser. Apple universal links launch the app, Android App Links open it without a disambiguation dialog, and no pixel loads.
The Google Play Install Referrer API returns an installed package's referrer URL. The deep linking guide covers the app side.
Link previews inflate clicks, so TrackRev flags bots and still redirects them. The bot filtering guide has the signals.
Test your own links on real phones
<pre id="out"></pre><script> var seen = document.cookie.match(/mt=(\d+)/); if (!seen) document.cookie = "mt=" + Date.now() + "; Max-Age=2592000; Path=/; Secure; SameSite=Lax"; document.getElementById("out").textContent = [ "UA: " + navigator.userAgent, "Referrer: " + (document.referrer || "(empty)"), "Query: " + (location.search || "(none)"), "Test cookie: " + (seen ? "kept, first set " + new Date(+seen[1]).toISOString() : "new this visit") ].join("\n");</script>| Step | Open the link in | Record |
|---|---|---|
| 1 | Facebook Messenger or Instagram on an iPhone, from a message to yourself | App name, referrer, and whether the cookie reads kept after the app closes |
| 2 | LinkedIn on an iPhone | The same 3 readings |
| 3 | Messages and Apple Mail, with a fake gclid on the destination | Whether the utm_ tags and the gclid arrive |
| 4 | A Safari Private Browsing tab | Whether the utm_ tags and the gclid arrive |
| 5 | Google Chrome on an Android phone | The control, where every tag arrives and the cookie reads kept |
| 6 | Mobile Safari, 8 days after its first visit to the page, with no visit in between | Whether the script-written cookie is gone |
| 7 | Every new iOS release, such as iOS 26 in September 2025 | Repeat steps 3 and 4, since Apple names no parameters |
Open each link 2 times: once straight away and once after fully closing the app.
Size the gap before you rebuild anything
Android is a fair control because none of Apple's rules apply to it. Post 1 link in 1 campaign, then compare conversion rates by platform.
| Platform | Clicks | Signups | Conversion rate |
|---|---|---|---|
| iPhone | 1,200 | 24 | 2.0% |
| Android | 800 | 40 | 5.0% |
| iPhone at Android's rate | 1,200 | 60 | 5.0% |
| Difference | None | 36 | 3.0 points |
Invented numbers. About 36 signups are filed as Direct or missing, which is $1,404 a month on a $39 plan if all of them paid. Treat 36 as an upper bound, since iPhone and Android audiences differ.
Write the visitor ID onto the payment
An ID stored on the payment cannot expire with a cookie: Stripe Payment Links take client_reference_id as a URL parameter, and Stripe Checkout Sessions take both fields below.
A "How did you hear about us?" signup field backs it up, as in self-reported versus tracked attribution.
| Stripe field | Holds | Limit |
|---|---|---|
| client_reference_id | A string you choose, returned in checkout.session.completed | 200 characters of letters, digits, dashes and the _ sign |
| metadata | Key-value pairs on a Stripe object | 50 pairs, keys to 40 characters, values to 500 |
A visitor ID in UUID form is 36 characters, so it fits both.
What TrackRev does about this
TrackRev is SaaS affiliate software with link tracking built in, and a TrackRev link redirects with a 302 and logs the click on the server before your page loads: time, country, city, device, browser, operating system and referrer.
The redirect adds the saved UTM tags and a _vid parameter to the destination. The pixel reads _vid on the first page view and writes a vid cookie with JavaScript, so Safari's 7-day limit applies to that copy.
The first-party tracking page lists what a link records.
A Stripe charge joins to its click through metadata.vid, then Stripe Checkout's client_reference_id, then the customer's email.
The browser breakdown has no in-app bucket, and an in-app visitor who returns in Safari without _vid joins a payment to the click only through an email identified earlier or a visitor ID already on the payment.
A link can also send iOS, Android and desktop visitors to different destinations, such as an App Store listing for iPhone taps. If you only want sessions by source, tagged links and Google Analytics 4 are free.
| Plan | Price | Links | Tracked events | Revenue by channel |
|---|---|---|---|---|
| Free | $0 | 50 | 1,000 a month | Hidden |
| Indie | $29 a month | Unlimited | Unlimited | Shown |
| Growth | $299 a year | Unlimited | Unlimited | Shown |
TrackRev plans for link tracking, October 2026. See pricing.
Found this useful? Share it.
Frequently asked questions
- Preview fetches inflate clicks, buyers return in another browser, or they sign up more than 7 days after the click.
- Read the User-Agent. Matomo Device Detector matches Instagram, FBAN, FBAV, MetaIAB, LinkedIn, TikTok and Snapchat.
- Usually. Stape says utm_ tags are not stripped in Safari Private Browsing, while gclid and fbclid may be.
- 5 items: the referrer URL, the referrer click timestamp, the install start timestamp, the app version at first install, and whether the user opened the app's instant experience in the past 7 days. It needs Google Play app 8.3.73 or later.
- Yes, when the tag waits for consent. TrackRev's pixel with data-requires-consent set to true sends nothing until your banner calls window.trk.grantConsent(), while the redirect still logs the click.
- No. Intelligent Tracking Prevention 2.2 applies it only when a domain Safari classifies as a cross-site tracker sends the visitor to a URL with a query string or fragment.

Written by
Founder, TrackRev.io & Contant.io
Muzahid Maruf founded TrackRev.io, SaaS affiliate software with no limit on tracked revenue, and Contant.io. He writes about affiliate programs.
Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth
Stop guessing where your revenue comes from.
Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.
Start free