Geo-targeted short links — region-aware redirects
Geo-targeted short links route visitors to country-specific destinations from one URL. Setup, real use cases, GDPR caveats, and the working policy pattern.
Geo-targeted short links send the same URL to different destinations based on the visitor's country — so linked.codes/p/buy shows the EU price page to a Berlin click, the US store to a New York click, and the Australia warehouse to a Sydney click. One slug printed on the poster, one URL in the tweet, one QR on the product packaging. The country lookup happens at the redirect edge in a few milliseconds and the visitor sees the right page on the first try.
This post covers the three use cases that genuinely need region-aware redirects (and the ones that don't), how country detection actually works under the hood, the GDPR question most platforms duck, the failure modes you only notice in production, and a policy you can paste into your short-link config. The widget further down builds the JSON rule set for you, country-by-country, and previews which destination a visitor from each region lands on.
Why country-aware redirects exist at all
The web is global by default but commerce is not. The same brand sells at €19 in Germany, $20 in the US, ¥3,000 in Japan, and ₹1,499 in India — and those numbers aren't a simple FX conversion. They reflect local VAT, local payment methods, local shipping economics, and what the market will bear. A flat "go to the US store" link served to every reader sends roughly five out of six paying customers to the wrong checkout, where the price is in the wrong currency, the shipping page warns about a six-week customs delay, and the call-to-action button is in a language they don't read.
Three concrete cases keep coming back when you talk to teams that actually run this.
The first is regional pricing. A SaaS that prices at $49/mo in North America runs a localised €39/mo in the EU and a $29/mo USD plan for India and South-East Asia (the "purchasing-power parity" tier). The same /pricing short link routes EU clicks to the euro page, Indian clicks to the PPP page, and everyone else to the headline page. The pricing pages aren't translations of each other; they're different products with different SKUs in the billing system. Sending an Indian visitor to the $49 page is not "a bit of friction" — it's a 10x mispricing and they bounce.
The second is language and content variants. A Berlin click on linked.codes/p/article lands on the German translation, a Paris click on the French one, a São Paulo click on the Portuguese one, and the default falls through to English. The article exists on four URLs; the short link picks the right one. This is the same routing logic that powers the device-targeted short links pattern — same slug, different destinations, branched by request signal — but the signal is country instead of OS.
The third is shipping rules and legal compliance. An e-commerce brand can't legally ship some categories to some countries — alcohol to Saudi Arabia, certain supplements to Germany, electronics with non-compliant power adapters to the EU. A QR code on a billboard in Frankfurt that points at a "buy now" page for a product that can't be sold in Germany burns trust as fast as it converts. The geo-aware redirect either swaps in the legally-shippable EU variant or sends the visitor to a "this product isn't available in your region" page that points at the closest live alternative.
The thing tying all three cases together is that the right destination depends on a fact about the visitor the link itself doesn't know — and can't, because it's the same short link for everyone. The redirect layer is the only place this branching belongs.
How country detection actually works
The visitor's country is inferred from the IP address of the request. The lookup happens server-side, before the redirect is issued, so the user never sees the inferred country in a URL or a query parameter — they just get the right destination.
Behind the scenes, every short-link platform that supports geo-routing is doing one of two things. Either it's calling out to a third-party geo-IP service (MaxMind GeoLite2, ipinfo.io, ipapi.co), or it's running the lookup natively because it sits on infrastructure that already does it. Cloudflare Workers, Fastly Compute, AWS CloudFront, and Vercel Edge all attach a country field to every incoming request based on their internal geo databases. The redirect handler reads that field, branches on it, and returns the right Location header.
The country itself is reported as an ISO 3166-1 alpha-2 code — DE for Germany, US for the United States, IN for India, GB for the United Kingdom (not UK, which is a trap that catches people on day one). The full list is maintained by the ISO, and every geo-IP service uses the same codes, which means routing rules are portable across providers if you ever swap. If you're writing the rules by hand, keep the ISO 3166-1 reference open in another tab.
A few facts about the lookup that change how you design rules.
Country accuracy at the edge runs around 97–99% for fixed-line broadband, drops to roughly 95% for mobile carriers (because mobile IPs roam more), and is essentially noise inside VPN exit ranges. For city-level routing it's much lower — 70% is a generous read, and you shouldn't build pricing logic on it. Country-level is the granularity that holds up in production; anything finer is for analytics, not routing.
The lookup is also free from the visitor's perspective. No extra request, no JavaScript, no GDPR-relevant cookie. The server already has the IP because it had to receive the request; it just enriches the IP with a country code before deciding where to redirect. That's part of why this pattern survived even as third-party tracking got harder.
The five real use cases — and the ones to skip
Five patterns where country routing pays off, in rough order of how often they show up in production.
Regional pricing pages. Same product, different price, different currency, different VAT treatment. The classic. EU readers go to the euro page with VAT included, US readers see the USD page with sales tax calculated at checkout, UK readers get the GBP variant. Anyone running PPP pricing for emerging markets has a third or fourth tier. Without geo routing you either show every visitor the highest-priced page (and lose 60% of the market) or you build a country-picker on the destination page (which adds a click and lies to your analytics about referrer source).
Language variants of content. The same article in five languages. The same product page localised for each market. The same landing page for a campaign that ran in three regions. Geo routing doesn't replace the Accept-Language HTTP header — that's still the gold standard for "what language does this visitor read", and the multilingual QR redirect playbook covers the fallback chain in operational detail — but country is a reliable second signal when the browser language is ambiguous (English-as-second-language users browsing in English on a German Windows install, for example). The combination is stronger than either alone.
Shipping and legal compliance. Products that can't legally be sold to certain countries. Subscriptions that don't operate in some regions. Pages with age-verification or country-specific consent flows. The Brazilian visitor lands on the LGPD-compliant signup, the EU visitor on the GDPR variant, the California visitor on the CCPA-compliant one. Same short link, different legal boilerplate.
Affiliate and reseller routing. A global brand with regional resellers — clicks from each region go to the local distributor's storefront. A SaaS with affiliate partners in different countries — the right partner gets credited for each click. The link itself doesn't expose the routing logic, which is what makes it work in print and on packaging where the affiliate ID can't be visible.
Bilingual support hand-off. Help-centre and contact-form links that route to the right support team. Asia-Pacific clicks go to the JP-language help desk, EU clicks go to the multilingual queue with hours that match local time, North America falls through to the US team. Saves the time-zone confusion that kills response rates.
Platform handles where adoption is uneven by country. The clearest case is social platforms that launched in some markets before others. The same printed QR campaign that ships to the US, UK, and India can route to a Threads handle, while the EU and South-East Asia variants route to alternatives the audience actually uses — the regional adoption map that decides whether a Threads QR earns its print cost sets out the strong/mid/weak markets the routing should respect.
The cases worth not using country routing for, even when it's tempting:
- Generic "is this a US site?" prompts. If the right answer for an unrecognised country is the US site anyway, you don't need country routing — you need a default destination. Country routing adds machinery for no benefit.
- VAT calculation on a single checkout. The checkout itself should handle VAT based on the billing address the user enters. Routing them to a "VAT page" by IP doesn't replace that calculation and creates a sync problem when the IP-country and billing-country disagree.
- GDPR consent banners. Don't suppress the consent banner for non-EU IPs. The banner is cheap, the privacy posture is consistent, and the day a researcher visits via a US VPN to fact-check you is the day this decision blows up in your face.
- Showing or hiding content based on country. If the product itself isn't legal somewhere, route to a "not available in your region" page — don't try to serve the same URL with content hidden. The page on the visible URL becomes a soft-404 in Google's eyes and the indexer gets confused.
The GDPR question — answered straight
Country-routing a redirect is not, by itself, processing personal data for a marketing purpose. The IP address is read from the network packet that the visitor's own request generates, used in-memory to decide where to redirect, and discarded once the redirect is issued. Nothing is stored, nothing is sent to a third party for the routing decision itself, and the routing is identical to choosing a server location based on physical proximity — which is what every CDN already does.
The line you cross into GDPR territory is when you log the IP-to-country mapping persistently, especially when joined with other identifiers. Geo-IP analytics — "clicks by country" charts in your dashboard — is generally fine because it's aggregated and de-identified at the storage layer. Per-click country logs that join with a user ID, an email address, or a session cookie are personal data under GDPR Article 4(1), and you need a lawful basis (consent for marketing, legitimate interest for security and fraud) and a privacy notice that mentions it.
The Court of Justice of the European Union's 2016 Breyer ruling settled the IP-address-as-personal-data question for the EU — dynamic IPs are personal data when the website operator can plausibly link them back to an individual. For most short-link platforms storing IP-derived country codes against click events for analytics, that's a yes. The practical implications: don't store raw IPs longer than you have to for security and fraud purposes (30–90 days is typical), strip them from analytics aggregation pipelines, document the country lookup in your privacy notice, and treat the geo-IP service as a sub-processor in your DPA.
Country routing is one of the few personalisation patterns that doesn't require a consent banner — but only if you don't log the result against an identifiable user.
This is also why country routing pairs cleanly with the UTM tagging conventions for short links. The UTM tells you which campaign and channel; the country lookup tells you which geographic segment converted. Both can live in your analytics without joining either back to a personal identifier — which is the privacy posture you want.
Failure modes you only notice in production
Six things that fall over when geo-routing leaves the lab, in roughly the order they bite.
VPN exit nodes pretend to be everywhere. A Brazilian customer using a US VPN to watch Netflix shows up as a US IP. The routing fires US, the page is in English, the price is in USD, and the customer thinks the brand doesn't ship to Brazil. About 5% of public web traffic is now identifiably VPN, with mobile rates higher than desktop, and the misrouting is real. Don't try to detect-and-correct; just make sure the country picker on the destination page is visible enough that the user can flip it manually. Show, don't override.
Mobile carrier IPs roam. A user landing at Heathrow with a German phone on EU-wide roaming might appear as either a UK or a DE IP depending on which carrier infrastructure routed the request. The same physical person, two different routing outcomes between Tuesday and Wednesday. This is a known issue in MaxMind's documentation and affects most travelling visitors. Don't build single-click pricing flows that assume the country IP-detected on click 1 will match the country IP-detected on click 2.
Tor exit nodes show as random countries. Tor users see whichever country happens to be hosting the exit relay their circuit ended up using — often Germany, Netherlands, Romania, or the US. If your routing accidentally serves the wrong country page to a privacy-conscious visitor, the visible bounce isn't fixable, but the invisible failure — quietly serving DE pricing to a UK user — is the one that hurts.
GB is not UK. ISO 3166-1 codes the United Kingdom as GB, but the top-level domain is .uk, the currency is GBP, and the colloquial reference is "UK." Every team writing rules by hand types UK somewhere on the first day and the rule never matches anything. The country UK exists in ISO 3166-1 only as a reserved code for the United Kingdom of Great Britain and Northern Ireland and is not what geo-IP services return. Use GB. Read your rules before you ship them.
EU is not a country. There is no EU code in ISO 3166-1. If you want to route all EU visitors to a single destination, your rule needs to list the 27 member-state codes — DE, FR, IT, ES, NL, BE, AT, IE, PT, GR, PL, CZ, HU, RO, SE, DK, FI, BG, HR, SK, SI, EE, LV, LT, LU, CY, MT. Most platforms let you define a country group (group: "EU") once and reference it from each rule, but you still need to maintain the membership list when countries join or leave — Croatia joined in 2013 and adopted the euro in 2023; the UK left in 2020; both are recent enough that older docs still get it wrong.
The default is also a rule. Every visitor whose country didn't match anything ends up on the default. If you forget to set the default, most platforms 404 (or 302 to the platform's marketing page, which is worse). The default should always be the global English page — the closest thing to a sensible answer for a Slovenian visitor when you only built rules for DE, FR, IT, ES. Set the default first, then add country rules on top.
Region grouping versus per-country rules
There's a design decision worth getting right early: do you write one rule per country, or do you group countries into regions?
Per-country rules give you precision. Sweden and Norway both end up in "northern Europe" linguistically but their VAT treatment, payment methods, and shipping economics are different enough that you might want different destinations. The cost is maintenance — every country you care about is a separate rule, and adding a market means another entry.
Region grouping (EU, LATAM, SEA) gives you cleanliness. Five rules cover the world. The cost is precision — you lose the ability to handle Germany differently from France inside the EU bucket. Most teams that ship region-grouped routing eventually carve out one or two countries from a group (Switzerland out of EU because it isn't actually in the EU, India out of "SEA" because PPP pricing makes the economics special) and accept the hybrid.
The pragmatic pattern: start with three or four region groups for the majority of your traffic, add per-country exceptions only when the data shows the group's destination is wrong for a specific market. Don't write 195 rules on day one — you don't have the data to know which ones matter yet.
Run one short link across regional pricing, language variants, and shipping rules — country lookup at the edge, branded redirect host, full analytics by country.
Set up geo-targeted linksA working policy block
Here's the shape most short-link platforms accept (or convert to). The widget below builds your variant.
{
"rules": [
{ "match": { "country_in": ["DE","FR","IT","ES","NL","BE","AT","IE","PT"] }, "destination": "https://eu.example.com/" },
{ "match": { "country_in": ["GB"] }, "destination": "https://uk.example.com/" },
{ "match": { "country_in": ["IN","ID","PH","VN","TH"] }, "destination": "https://in.example.com/" },
{ "match": { "country_in": ["US","CA"] }, "destination": "https://example.com/" },
{ "match": "default", "destination": "https://example.com/intl" }
]
}
Order matters. The first matching rule wins. Put narrow rules (GB) above broad ones (EU group) if a country could land in both. Always end with a default. The configuration surface on Linked.Codes lives in the short-links docs; the analytics that show which country actually clicked is documented in the traffic docs.
Build your geo-routing rule
Drop in the destinations for each region. The widget produces the JSON-shaped policy block and previews which country lands where.
The defaults populate with a generic regional-pricing setup — EU, UK, US/CA, India/SEA, and a global default. Edit the destinations and the policy JSON updates live; flip the preview country to see which rule fires for that region.
What to look for in a short-link platform
Three things separate platforms that handle this cleanly from ones that almost do.
Country lookup at the edge, not on the destination. Some platforms accept a "geo target" config but only act on it after the redirect has already fired — they 302 to a JavaScript-shim page that reads the visitor's IP client-side and re-redirects. This adds 100–500ms, breaks crawlers, and double-bills your analytics. Verify the routing happens server-side before the 302 — the visitor should see one redirect chain, not two. The platforms that get this right are running on edge infrastructure (Cloudflare Workers, Fastly, Vercel Edge); the ones that don't are usually traditional origin-server setups bolted on with a JavaScript geo shim.
Per-country and region-group rules in the same rule set. You should be able to say "EU → A, but Germany → B" without writing 26 rules manually. The platform should let you define a country group once, reference it from a rule, and override it with narrower rules above. If the UI only supports per-country rules or only supports flat region groups, you're going to outgrow it in a year.
Country attribution in the analytics. The click logs need to show which country fired each rule, not just total clicks per short link. Without the per-country breakdown, you can't tell if a rule is firing wrong (Italian clicks landing on the UK page because of a typo) and you can't measure whether a regional destination is actually performing.
Linked.Codes ships all three. If you're auditing other platforms, the Bitly alternatives in 2026 breakdown covers which ones get the edge-side routing right and which ones don't. For the underlying pattern — same slug, different destinations branched by request signal — the device-targeted short links post walks through the equivalent setup for OS rather than country, and many teams end up combining both rules in the same link.
Analytics — what country-level click data actually tells you
The honest answer: country-level click data is good enough to inform routing decisions, marketing spend allocation, and product roadmap. It's not good enough to make per-user personalisation calls. The 97–99% country accuracy means about 2% of clicks attributed to the wrong country on any given day, which is fine for "we're getting 30% of clicks from Germany, the EU page is worth maintaining" and not fine for "this specific visitor is in Germany, charge in euros."
The metrics worth pulling out of country-level click data, in order of how often they change a decision:
Country mix per link. Reveals which markets your content actually reaches versus which ones you assumed it did. A "global" campaign that turns out to be 80% US clicks is a positioning problem, not a budget problem.
Conversion rate per country. If the EU page converts at 3% and the US page converts at 1%, that's either a pricing mismatch (US visitors aren't ready to pay your headline price) or a content mismatch (your value prop reads as European). Both are worth fixing.
Time-to-first-click by country. Posts shared at 10am Berlin time get their first wave of EU clicks immediately, then a US wave six hours later. Knowing the country distribution lets you predict the time-shape of a campaign and not panic if traffic looks "slow" two hours after publish.
Default-rule traffic share. If more than 20% of clicks are falling into the default rule, your country list is missing a market that matters. Most teams discover their long-tail markets this way — "wait, we have meaningful Indonesia traffic?" — and then add rules accordingly.
The platform-side surface for all of this on Linked.Codes is documented in the traffic docs linked above; for a one-off geo-targeted link you can build it directly in the free short-link generator and pick the destinations as you go.
When NOT to use geo-targeted short links
Worth being honest about the cases where this pattern hurts more than it helps.
Single-market businesses. If you sell only to Australia, route all clicks to the AU page and don't dress it up as "geo-targeted." Adding a rules engine over a one-destination link adds nothing but failure surface.
Heavily-personalised content. If the routing decision needs to factor in user history, account state, or behaviour — country alone isn't enough. Build the personalisation into the destination page where you have session context, not into the short-link redirect.
A/B tests across countries. A/B testing implies splitting visitors into experimental groups; country routing implies deterministic mapping. Mixing them — "show variant A to half of EU visitors and variant B to the other half" — needs a test-bucket layer on top of the geo rule, which is usually best handled by your experimentation tool downstream of the redirect, not in the redirect itself.
Tracking-sensitive contexts. Some campaigns explicitly promise not to vary content by IP — research surveys, journalism source-tools, privacy-conscious communities. Don't break that promise with silent geo routing.
Related reading
- Device-targeted short links — mobile vs desktop redirects — the OS-and-browser equivalent of the country pattern; same rule shape, different signal.
- UTM parameters that actually matter for short links — campaign attribution layered on top of geo-aware routing.
- Time-limited short links — expiring URLs done right — how to retire geo-targeted campaign links cleanly when the regional window closes.
- Branded short links — why your domain beats bit.ly — the domain layer that carries the country rules.
- Bitly alternatives in 2026 — the field of short-link platforms that handle geo routing well, and the ones that fake it.
- Real-time link analytics — watching country-level click data as a campaign goes live.
How accurate is IP-to-country lookup?
Around 97-99% for fixed-line broadband, 95% for mobile carriers, and effectively useless inside VPN exit ranges. Country-level granularity holds up well enough for routing decisions; city-level is closer to 70% and shouldn't be used for pricing logic. The 1-3% misroute rate is unavoidable and usually self-corrects on the destination page if you keep a visible country picker.
Do I need consent banners for geo-targeted short links?
Not for the routing itself, as long as the IP-to-country lookup is in-memory and not stored against a personal identifier. You do need to mention the country lookup in your privacy notice and treat your geo-IP provider (MaxMind, ipinfo, Cloudflare, etc.) as a sub-processor in your DPA. Per-click country analytics joined with user IDs is personal data under GDPR and needs a lawful basis.
What happens for visitors using a VPN?
They land on whatever country the VPN's exit node reports — often the US, Netherlands, or Germany. The misroute is invisible to the visitor unless they realise the page is in the wrong language or currency. The fix isn't to detect-and-correct (VPN detection is unreliable) but to keep a visible country picker on the destination page so users can manually flip if needed.
Can I geo-route based on city or region?
Technically yes, practically no. City-level IP accuracy runs around 70% — too low to be safe for pricing or shipping decisions. Region-level (state, province) is similar. Use country-level for routing logic and treat finer geography as analytics-only signal.
What's the difference between geo-routing and Accept-Language routing?
Geo-routing reads the visitor's country from their IP; Accept-Language routing reads the language they configured in their browser. They're different signals. A German visitor in Spain on holiday has a DE browser and an ES IP — the right answer is usually the German page (their language) not the Spanish one (their geography). Use Accept-Language as the primary signal for language variants, and country as a fallback or as the signal for non-language-driven branching like pricing.
Should the EU be one rule or 27 rules?
One rule with a country group containing the 27 member-state codes, unless you actually need per-country variation inside the EU (different VAT pages, different shipping rules per market). Most teams start with the one-rule version and carve out exceptions only when data shows a specific country deserves its own destination. Don't write 27 rules just because the group exists.
Does geo-routing hurt SEO?
Not if the routing handles search-engine crawlers correctly. Googlebot crawls from US IPs by default and shouldn't see a geo-redirect at all — it should see the global default English page so it can index it. Configure the bot rule (same pattern as device-targeted links) to short-circuit country routing for known crawlers. Without that, geo-routing accidentally hides your international pages from Google's index.
Sourcesshow citations
- ISO 3166-1 alpha-2 country codes (authoritative list) — https://www.iso.org/obp/ui/#search/code/
- MaxMind GeoIP2 documentation — accuracy and database structure — https://dev.maxmind.com/geoip/docs/databases/city-and-country
- Cloudflare Workers — request.cf.country reference — https://developers.cloudflare.com/workers/runtime-apis/request/
- Court of Justice of the European Union — C-582/14 (Breyer, IP addresses as personal data) — https://curia.europa.eu/juris/document/document.jsf?docid=184668
- MDN — Accept-Language HTTP header — https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
- ITU — Individuals using the Internet (global statistics) — https://www.itu.int/en/ITU-D/Statistics/Pages/stat/default.aspx
Try it on your own domain
Branded short links and dynamic QR codes, on your subdomain or your own domain. One-time purchase, no per-click fees.