The scenario we hear almost every week: a Shopify shop sells in 12 countries, each with its own subdomain, translated catalog, local currency, and local payment gateway. The team hands out 12 different links to partners and creators — one per country. One partner mixes them up, another puts the Mexican link in a German blog, a third just shares en.shop.com everywhere. Result: 18% of traffic lands on the wrong region, conversion in those sessions is 3× lower.
The fix is one rule: give partners one link and let the backend decide where to send each visitor. That is a geo-redirect. Easy from the outside, with a few traps under the hood: VPN, country-language mismatches, SEO consequences. This piece — how to do it without the pain.
Country-level geo-redirect works at 99.6% accuracy on a good IP database. Language fallback via Accept-Language handles edge cases. VPN breaks geo in 8% of traffic — that segment should see a country selector instead of a forced redirect. SEO is solved with canonical + hreflang. For most teams, a geo-redirect plus an explicit “wrong region?” banner is enough.
How accurate is IP-based country detection?
All commercial IP databases (MaxMind GeoIP2, IP2Location, ipinfo, our internal one at TDS) cluster around the same accuracy:
- Country: 99.6% on good datasets. About 1 error per 250 users. Good enough for a commercial redirect.
- Region (state): 88–92%. Already noticeably worse. Marketplaces use it for tax and shipping; usually overkill for a redirect.
- City: 67–78%. Half of what IP service marketing claims. City-level redirects are almost always a bad idea.
Where the country-level errors come from. The main source is mobile networks. A provider with cross-border infrastructure assigns an IP that belongs to a Dutch ASN, even though the physical user is in Moscow. About 2–3% of mobile traffic falls into this, which is most of the 0.4% overall noise.
Takeaway: country-level redirects are safe. City-level — never without a language fallback.
Language fallback: when IP is not enough
There are scenarios where the IP says one country but the user speaks a different language. Switzerland is four-lingual: the IP says “CH”, the Accept-Language header says which language to greet them in. Real examples:
- a German on a business trip in Italy (IP=IT, Accept-Language=de-DE);
- a Russian speaker in Germany (IP=DE, Accept-Language=ru-RU);
- an English-speaking expat in Japan (IP=JP, Accept-Language=en-US).
The rule we recommend: geo decides currency and checkout, language decides UI. The Swiss user sees Swiss prices and the Swiss checkout, but the interface in their preferred language.
The Accept-Language header is often multi-part:
Accept-Language: de-DE, de;q=0.9, en;q=0.7, *;q=0.5
The user prefers German, then English. Parse by weight (q-parameter). On the backend this is ten lines of code or one rule field in TDS.
VPN: 8% of traffic that breaks geo
On our numbers, 5–12% of visitors to commercial sites use a VPN. Higher on privacy-focused products and media, lower on marketplaces. These users see geo that is not theirs. What to do:
- Do not block. The temptation to “cut off VPN traffic” comes up regularly, and it is always a bad idea: real people who just want privacy go along with the bots. Especially painful on B2B audiences.
- Do not auto-redirect to the “detected” country. Instead, show a selector at the top: “In the Netherlands? or pick another”. The user confirms or changes manually.
- Persist the choice in a long-lived cookie for a year. Do not re-trigger geo-redirect when the cookie already states a preference.
Good IP databases flag VPN addresses (is_proxy, type=hosting). Use that flag as a signal “geo is unreliable, ask the user”, not as “refuse to serve”.
Teams that do a hard geo-redirect with no confirmation banner lose 5–9% retention. It hurts expats and business travelers the most: the user is used to the US version, and from London gets bounced to the UK one — they assume they ended up in the wrong place. A selector at the top of the page fixes this in a day.
SEO: canonical and hreflang
Google dislikes the same URL serving different content to different visitors — it looks like cloaking. To avoid deindexing, two technical pieces matter:
-
Canonical URL. Each localized version declares itself
<link rel="canonical" href="https://es.shop.com/promo">. Google understands that the Spanish landing is a real separate page, not a duplicate. -
hreflang. Each version lists all the others:
Googlebot follows the links and understands the relationship. Without it, your regional versions compete with each other for ranking.<link rel="alternate" hreflang="es-ES" href="https://es.shop.com/promo"> <link rel="alternate" hreflang="mx" href="https://mx.shop.com/promo"> <link rel="alternate" hreflang="en" href="https://en.shop.com/promo"> <link rel="alternate" hreflang="x-default" href="https://en.shop.com/promo">
Googlebot itself is a separate story: it arrives from a US IP, and if you geo-redirect it to en.shop.com, it will only index the English version. Better: do not geo-redirect crawlers, serve them every version directly. In TDS the bot route (see how antibot works) sends Googlebot and Bingbot past the geo rules untouched.
When you do not need a geo-redirect at all
Geo-redirect is optional. Cases where it adds noise:
- Single-country shop. If you only sell in the US — extra logic for nothing.
- Content site without localization. Single-language blog, no regional adaptations. The visitor's browser figures it out.
- B2B SaaS with a global interface. One English landing for the world, one currency (USD), nothing to redirect.
- Landing tied to one ad campaign. If the campaign already targets a specific country in the ad-network settings, users are already arriving from the right geo.
What this looks like in TDS
A geo-redirect in TDS is a campaign rule with a condition list. Each rule says: “if country = X, send to URL = Y”. At the top — a special VPN route (detected as proxy → show selector); at the bottom — a required default. Every match is logged: detected country, whether the user hit the VPN flag, which rule fired.
Conveniences included: automatic hreflang generator for all your versions, a “do not redirect crawlers” toggle, long-lived cookie for confirmed country choice, and analytics on “how often users manually switched country” — the latter is a brutally honest metric of how well your geo assumptions match reality.
Conclusion
Geo-redirect is simple when done right. Three rules:
- Redirect by country, never by city.
- Do not block or auto-redirect VPN traffic — show a selector.
- Skip crawlers and tag your pages with canonical + hreflang.
Two or three markets and one currency? Skip the geo-redirect entirely. Twelve countries with local payments? Without one, life gets painful. Especially if you also need to route by device and source — in that case look at a full smart-link, where geo is one of six signals.