Device-targeting redirects: one link for the App Store, Google Play and the web
How device targeting redirects send iPhone, Android and desktop visitors to different URLs with one 302, where User-Agent rules fail, and how to test them.
Muzahid Maruf, FounderUpdated
On this page
- 01How device targeting redirects work
- 02Opening an installed app with Universal Links or App Links
- 03One QR code for every phone
- 04What changed in device detection: Safari 13 and Chrome 110
- 05In-app browsers and link previews
- 06301 versus 302: redirect type and caching
- 07Routing by country as well
- 08Setting up device rules in TrackRev
- 09Testing before you publish or print
Explore with AI
Opens this article inside the chosen assistant with a ready-made prompt.
A device targeting redirect is one short link that reads the User-Agent header on each click and answers with a 302 that sends iPhones to the App Store, Android phones to Google Play and desktops to a web page.
Set one destination per device class plus a default. The header separates phones from computers reliably.
It can't tell whether the app is installed, and it misreads spoofed strings and iPads, which have sent a Macintosh string by default since Safari 13 in 2019.
Key takeaways
- A 302 from a device targeting redirect can send iPhones to the App Store, Android phones to Google Play and desktops to a web page from one link.
- iPads have sent a Macintosh string by default since Safari 13 in 2019, so they take the desktop rule.
- A tap that opens an app through verified Universal Links or Android App Links never reaches your redirect, so it logs no click.
- Use a 302 or 307, never a 301 or 308, and key any CDN cache on User-Agent.
How device targeting redirects work
The browser's GET request carries a User-Agent header. The server sorts it into a device class and replies with a 302 and a Location header, so the visitor sees one hop.
MDN Web Docs prefers feature detection and Client Hints such as Sec-CH-UA-Mobile, but a redirect has no page to run it in.
Its shortcut for phones is to look for Mobi anywhere in the string and treat the rest as desktop.
User-Agent strings and the rule for each device
| Device | User-Agent string | Send it to |
|---|---|---|
| iPhone, Mobile Safari 26 | Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1 | Your App Store product page on apps.apple.com |
| Android phone, Google Chrome 143 | Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Mobile Safari/537.36 | Your Google Play listing, play.google.com/store/apps/details?id= plus the package name |
| Android phone, Microsoft Edge 141 | Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Mobile Safari/537.36 EdgA/141.0.0.0 | The same Google Play listing, because the Mobile token is still there |
| Windows PC, Google Chrome 143 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 | Web sign-up or pricing page, with a QR code that points back at the short link |
| Mac, Safari 26 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15 | Web sign-up or pricing page |
| Googlebot 2.1 | Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) | The desktop or default page: it should work on any screen and show both store badges |
| curl 7.64.1 | curl/7.64.1 | The desktop or default page |
Strings from MDN's User-Agent reference, last modified October 28, 2025.
Opening an installed app with Universal Links or App Links
Universal Links on iOS and Android App Links on Android 6 (API level 23) and later open an installed app straight from the tap. Apple Developer Documentation says the system skips the browser and your website.
The Android App Links guide adds that verified links skip the disambiguation dialog, and Dynamic App Links on Android 15 (API level 35) change the rules without an app release.
| Platform | File | Where it lives | Notes |
|---|---|---|---|
| iOS Universal Links | apple-app-site-association | https://yourdomain.com/.well-known/ over HTTPS with a valid certificate and no redirects; one file per subdomain | Since iOS 14 and macOS 11 devices fetch it through Apple's CDN, which requests it within 24 hours; devices recheck about weekly (associated domains documentation) |
| Android App Links | assetlinks.json | https://yourdomain.com/.well-known/assetlinks.json | Android 6 and later; must match the SHA-256 fingerprint of the app's signing certificate |
An app opened from the tap sends your server no request, so it logs no click unless the app reports the open.
Both files must sit on a domain you control, so a shared shortener can't open your app and a custom tracking domain can.
For a visitor who installs first, Android's Play Install Referrer API gives the app referral data for 90 days through client library 2.2, and the deep linking guide covers the rest.
One QR code for every phone
One QR code serves both stores when it points at a device-targeting redirect, and the destinations can change after the print run, as dynamic versus static QR codes explains.
The free QR code generator recommends printing at least 2 cm (0.8 in) wide with a 4-module margin.
I would scan the final artwork with the camera app before printing, since a scanner inside another app can open an in-app browser.
What changed in device detection: Safari 13 and Chrome 110
| When | Change | Effect on a redirect |
|---|---|---|
| September 19, 2019, Safari 13 with iOS 13 | Safari for iPad shows desktop websites, which Apple's release notes describe as the same sites as Safari for macOS | An iPad on default settings takes the desktop rule; a Mac string reporting more than 1 from navigator.maxTouchPoints is almost always an iPad |
| Google Chrome 101 | Minor version zeroed: Chrome/101.3.2.1 becomes Chrome/101.0.0.0 | None for device rules |
| Google Chrome 107 | Desktop version and CPU fixed, such as Windows NT 10.0; Win64; x64 | None: desktops stay desktops |
| Google Chrome 110, February 2023 | Android version and model fixed: Android 13; Pixel 7 becomes Android 10; K, per the Privacy Sandbox blog | Model rules stop working; Android and Mobile still match |
In-app browsers and link previews
| Client | Token it sends | What it does |
|---|---|---|
| Instagram, Facebook and LinkedIn in-app browsers | Instagram, FBAN, FBAV, MetaIAB, LinkedIn or LinkedInApp | Mobile rule fires, but each app decides whether a Universal Link or App Link opens your app |
| Slack link preview | Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots) | Reads oEmbed, Twitter Card and Open Graph tags with HTTP Range headers |
| Facebook link preview | facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php) | Reads Open Graph properties in the first 1 MB and needs an answer within a few seconds |
App tokens from the Matomo Device Detector; crawler strings from Slack and Meta documentation.
Preview fetchers take the desktop or default branch, so put Open Graph tags on that page.
The post on bot traffic filtering explains why those clicks are flagged and still redirected, and link tracking not working on mobile covers the rest.
301 versus 302: redirect type and caching
| Status | Name | Lifetime | Use it for device rules? |
|---|---|---|---|
| 301 | Moved Permanently | Meant to last forever | No |
| 308 | Permanent Redirect | Meant to last forever | No |
| 302 | Found | Temporary | Yes |
| 307 | Temporary Redirect | Temporary, method unchanged | Yes |
Status classes as described in the MDN redirection guide.
A permanent redirect kept by a browser or CDN pins the first device's answer for everyone behind it, and MDN's redirection guide says crawlers replace the original URL after one.
Google Search Central names Vary: user-agent for URLs that differ by device, so key any CDN cache the same way or skip caching.
Routing by country as well
Country routing resolves the click's IP address to a country and picks the destination mapped to it. MaxMind's accuracy page estimates 99.8% for country, so route on country and nothing finer.
A VPN user appears at the VPN's server, so write a default for every unmatched country, route price by country and language by the Accept-Language header, and keep legal restrictions in the destination.
| Resolution | MaxMind estimate | Safe to route on? |
|---|---|---|
| Country | 99.8% | Yes, for a storefront, currency or legal page |
| US state or region | About 80% | Only as a soft preference |
| US city, within 50 km | 66% | No |
MaxMind's published estimates for its GeoIP products.
Setting up device rules in TrackRev
TrackRev stores the country and city of every click but routes by device only.
The Add device targeting option on the link form takes a mobile destination and a desktop destination, and a blank field falls back to the main URL.
Phones share the mobile field, tablets take the main URL and an iPad in default mode takes the desktop field.
One mobile field means one phone destination, so split iPhone from Android with a page on your own domain, or use one link per store. This route handler does the first.
import { NextRequest, NextResponse } from "next/server"; const IOS = "https://apps.apple.com/app/id0000000000"; // your App Store listingconst ANDROID = "https://play.google.com/store/apps/details?id=com.example.app";const WEB = "https://example.com/signup"; export function GET(req: NextRequest) { const ua = req.headers.get("user-agent") ?? ""; if (/iPhone|iPod/.test(ua)) return NextResponse.redirect(IOS, 302); if (/Android/.test(ua) && /Mobi/.test(ua)) return NextResponse.redirect(ANDROID, 302); return NextResponse.redirect(WEB, 302);}Every click row keeps the device class, operating system, browser and country, so counts split by iPhone, Android and desktop on the free plan, which costs $0 and allows 50 links and 1,000 tracked events a month.
Paid plans add the revenue those clicks led to, synced from Stripe, Paddle, Polar or Lemon Squeezy: Starter is $39 a month, Growth $99 and Scale $199, as the pricing page lists.
To open an installed app, enter its identifiers under domain settings and TrackRev serves both association files on your verified custom domain.
It is not a mobile measurement partner, so in-app event attribution needs a tool such as AppsFlyer or Adjust.
Testing before you publish or print
| Device | Open it from | Should land on |
|---|---|---|
| iPhone, Safari 26 | Safari, then the Camera app scanning a code made from the link | The App Store listing |
| Android phone, Chrome 143 | Chrome, then the camera | The Google Play listing |
| Windows PC, Mac or iPad | Any browser | The web sign-up page |
| Any phone | Instagram, LinkedIn and Mail | The store, the app or a blank page |
| Slack | Paste the link into a channel | A card with your Open Graph title and image |
Running curl with the iPhone string from the table prints the 302 status line and the Location header, so you can confirm the rule before picking up a phone.
curl -s -o /dev/null -D - \
-A "Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1" \
https://go.example.com/appFound this useful? Share it.
Frequently asked questions
- Yes, by matching iPhone, or Android with Mobile. TrackRev's link form has one mobile field, so splitting the App Store from Google Play takes a page of your own or one link per store.
- It reads the User-Agent header. Chrome also sends Sec-CH-UA-Mobile, which is ?1 on a phone, and Sec-CH-UA-Platform by default.
- Only if the domain serves apple-app-site-association for iOS and assetlinks.json for Android. Otherwise the person lands on the App Store or Google Play page and taps Open.
- No. Chrome omits Mobile on tablets and default Safari on iPad reads as a Mac, so in TrackRev a tablet takes the main URL and an iPad takes the desktop field.
- No. TrackRev records each click's country but routes by device only, so use another tool or a country selector on your own page.
- Yes, within 50 links and 1,000 tracked events a month. Revenue figures and the affiliate or referral program need a paid plan from $39 a month.

Written by
Founder, TrackRev.io & Contant.io
Muzahid Maruf is the founder of TrackRev.io and Contant.io. He writes about marketing attribution, link tracking, and revenue analytics for SaaS teams.
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