DEV Community

Cover image for How to share one App Store link that works in every country
WIO
WIO

Posted on

How to share one App Store link that works in every country

If you've ever put an App Store link in a tweet, a README, or a newsletter, you've probably copied it straight from your browser:

https://apps.apple.com/us/app/your-app/id1232780281
Enter fullscreen mode Exit fullscreen mode

That /us/ is the problem. App Store web links carry a two-letter country code, because Apple runs a separate store (a "storefront") for each country. Someone in Japan who taps a /us/ link is looking at the US store. And if your app isn't sold in their country at all, they hit Apple's "This app is not available in your country or region" message instead of your app.

Making a separate link for every country isn't realistic. You'd need to know where each reader is before they click. So the link has to work it out at click time.

The useful fact: the app ID never changes

Every app has a numeric ID, the id1232780281 part. It's the same in every country. The only thing that changes between storefronts is the country code:

apps.apple.com/us/app/id1232780281
apps.apple.com/jp/app/id1232780281
apps.apple.com/de/app/id1232780281
Enter fullscreen mode Exit fullscreen mode

So if you know the visitor's country and you know the app is sold there, you can build the right URL yourself.

Step 1: where is the visitor?

If your code runs on Cloudflare Workers, you get this for free. Cloudflare attaches the visitor's country to every request as request.cf.country, an ISO code like JP. Two values need care: XX means unknown and T1 means Tor. Treat both as "no country".

function normalizeCountry(raw: unknown): string | null {
  if (typeof raw !== "string" || !/^[A-Za-z]{2}$/.test(raw)) return null;
  const cc = raw.toLowerCase();
  return cc === "xx" || cc === "t1" ? null : cc;
}
Enter fullscreen mode Exit fullscreen mode

When the country is unknown, the safest redirect is Apple's country-less link, https://apps.apple.com/app/id<ID>, and Apple picks the store.

Step 2: is the app sold there?

Apple has a public lookup endpoint (the old iTunes Search API) that answers this:

https://itunes.apple.com/lookup?id=1232780281&country=jp
Enter fullscreen mode Exit fullscreen mode

If the app is in that storefront you get resultCount: 1 plus its name and icon. If it isn't, you get resultCount: 0. No key needed.

The endpoint is rate-limited, so don't call it on every click. On Workers you can cache the fetch at the edge:

const res = await fetch(url, { cf: { cacheTtl: 86400, cacheEverything: true } });
Enter fullscreen mode Exit fullscreen mode

A day of caching means Apple only gets asked about each app and country pair occasionally. The trade-off: when an app launches in a new country, detection can lag by up to a day.

Step 3: when it isn't sold there

Now you need a fallback. Most apps are in the US store, so check that first, then walk a list of other large storefronts (UK, Canada, Australia, Germany, France, Japan and so on) until one says yes.

On a computer or Android phone, you can just redirect to that store's page. The visitor sees the app, its screenshots, its description.

The iPhone catch

This is the part that surprised me. On iPhone and iPad, App Store links open in the App Store app, and the App Store app can only show the store for the account's own country. So redirecting a visitor in, say, Brazil to the /us/ page doesn't show them the US page. It ends in the same "not available" message you were trying to avoid.

The only honest fix is to not redirect. Instead, show a small page with the app's icon and name (both come from the lookup response) and a button to the store that has it. At least the visitor sees which app you meant and where it's sold. It's less magic than a redirect, but it doesn't dead-end.

One more failure case

If Apple's endpoint is down or returns an error, don't show an error page. Send the visitor to their own country's page. Most of the time the app is sold there anyway.

Putting it together: Hither

I wrapped all of this into a small free tool called Hither. You paste any App Store link (from any country) or a bare app ID, and you get:

hither.link/1232780281
Enter fullscreen mode Exit fullscreen mode

The link holds only the app ID, so there's no database. The same app always gets the same link, links don't expire, and nobody can change where a link goes, because everything else comes from Apple at click time. There's no account. You can even make your link before launch, using the Apple ID from your app's App Information page in App Store Connect, and put it on your landing page ahead of time.

Run your own copy

The code is on GitHub under the MIT license. It's a single Cloudflare Worker, and the Apple-specific bits live in one file (src/apple.ts) while the routing decision is pure, tested logic (src/decide.ts).

npm install
npm test
npm run dev
Enter fullscreen mode Exit fullscreen mode

To deploy to your own domain:

npx wrangler login
CLOUDFLARE_ACCOUNT_ID=your-account-id npm run deploy
Enter fullscreen mode Exit fullscreen mode

Change the domain in wrangler.toml, public/robots.txt and public/sitemap.xml first. On Cloudflare's free plan a Worker handles 100,000 requests a day, and going over makes requests fail until the daily reset instead of producing a bill.

Ideas on the list: Google Play links, custom short names (with a way to prove you own the app), and a QR code per link. If you've hit other edge cases with App Store links across countries, I'd like to hear about them in the comments.

Top comments (0)