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 — Founder of TrackRev.io

Muzahid MarufUpdated

Link tracking · 7 min read
On this page
  1. 01Why link tracking is not working on mobile
  2. 02In-app browsers keep their own storage
  3. 03Safari deletes cookies that JavaScript writes
  4. 04iOS 17 removes some parameters before your server sees them
  5. 05Blank referrers, app links and preview fetches
  6. 06Test your own links on real phones
  7. 07Size the gap before you rebuild anything
  8. 08Write the visitor ID onto the payment
  9. 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.
What you seeLikely causeWhat fixes it
Many clicks, few signups from Instagram or FacebookAn in-app browser with separate storageLog the click at a redirect
Direct signups 8 or more days after a clickSafari's 7-day cookie capKeep the visitor ID on the server
No UTM tags or gclid on iPhoneiOS 17 Link Tracking Protection in Safari 17.0Put the source in the link path
Social clicks with no RefererApp browsers that send none1 link per channel
A click, then no page viewUniversal link or Android App LinkPass the click ID into the app
iPhone converts far below Android, such as 2.0% against 5.0%Loss on the Apple sideFix the Apple-side rows above
Clicks that no person madeLink previews and prefetchesFlag bots, still redirect

In-app browsers keep their own storage

BrowserWhat is documentedSource
SFSafariViewController on iOSApple says an app cannot access its website data and points to ASWebAuthenticationSession for sharing data with SafariApple Developer Documentation
Instagram and Facebook on iOSCustom in-app browsers, not SFSafariViewControllerFelix Krause, August 10, 2022
WebView on AndroidDoes not share state with the browserChrome Custom Tabs documentation
Chrome Custom Tabs on AndroidShares the browser's cookie jarChrome 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.

Flag in-app browsers at the redirect (Node)
// 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

RuleDateWhat it limitsWhat it leaves alone
Intelligent Tracking Prevention 2.1February 21, 2019 (Safari 12.1 and iOS 12.2 betas)Cookies from document.cookie expire in 7 daysCookies set in an HTTP response
Intelligent Tracking Prevention 2.2April 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 fragmentCookies set in an HTTP response
Script-writeable storage capCurrent WebKit pageIndexedDB, LocalStorage, SessionStorage and Service Worker data deleted after 7 days without interactionHome Screen web apps
Advanced Fingerprinting ProtectionSeptember 15, 2025 (Safari 26.0)Known fingerprinting scripts cannot set long-lived cookies or LocalStorage, or read query parameters and document.referrerScripts Safari does not classify as fingerprinting
CNAME and IP cloaking defenseCurrent WebKit pageResponse cookies capped at 7 days when cloaking is detectedOther response cookies
Signs upDays after clickScript cookieAfter a tracker linkClick row
Wednesday, October 72PresentGonePresent
Sunday, October 116PresentGonePresent
Tuesday, October 138GoneGonePresent
Monday, October 1914GoneGonePresent
Monday, November 228GoneGonePresent
Monday, December 763GoneGonePresent

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.

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.

A test page that prints what the browser sends and whether its cookie survived
<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>
StepOpen the link inRecord
1Facebook Messenger or Instagram on an iPhone, from a message to yourselfApp name, referrer, and whether the cookie reads kept after the app closes
2LinkedIn on an iPhoneThe same 3 readings
3Messages and Apple Mail, with a fake gclid on the destinationWhether the utm_ tags and the gclid arrive
4A Safari Private Browsing tabWhether the utm_ tags and the gclid arrive
5Google Chrome on an Android phoneThe control, where every tag arrives and the cookie reads kept
6Mobile Safari, 8 days after its first visit to the page, with no visit in betweenWhether the script-written cookie is gone
7Every new iOS release, such as iOS 26 in September 2025Repeat 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.

PlatformClicksSignupsConversion rate
iPhone1,200242.0%
Android800405.0%
iPhone at Android's rate1,200605.0%
DifferenceNone363.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 fieldHoldsLimit
client_reference_idA string you choose, returned in checkout.session.completed200 characters of letters, digits, dashes and the _ sign
metadataKey-value pairs on a Stripe object50 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.

PlanPriceLinksTracked eventsRevenue by channel
Free$0501,000 a monthHidden
Indie$29 a monthUnlimitedUnlimitedShown
Growth$299 a yearUnlimitedUnlimitedShown

TrackRev plans for link tracking, October 2026. See pricing.

Found this useful? Share it.

PostLinkedIn

Frequently asked questions

Muzahid Maruf — Founder of TrackRev.io

Written by

Muzahid Maruf

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