How to Redirect Users Based on IP Address (Code Examples + No-Code)
Every method for IP-based redirects: edge workers, server-side Node.js and PHP, Nginx/Apache config, and no-code tools. Includes code examples, X-Forwarded-For handling, IPv6 notes, SEO rules, and VPN edge cases.

Every device connected to the internet has an IP address, and every IP address maps to a physical location. This means you can detect where your visitors are and redirect them to a page tailored for their region — a localized storefront, a language-specific landing page, or a compliance-appropriate version of your site. IP-based redirects are the foundation of geo-targeting, and this guide covers every method to implement them in 2026.
How IP geolocation works
When a visitor loads your website, their request includes an IP address. Geolocation databases like MaxMind GeoIP2 maintain mappings between IP ranges and geographic locations. These databases are built from data provided by Regional Internet Registries (RIRs), ISP records, and supplementary data sources.
The accuracy varies by granularity. MaxMind reports the following accuracy levels for their GeoIP2 database:
- Country level: 99.5% accurate. For country-based redirects, this is effectively a solved problem.
- State/region level: 80-90% accurate. Reliable enough for state-level content personalization.
- City level: 70-80% accurate. Useful for local promotions but not precise enough for critical routing decisions.
You can test how your own IP resolves using our free IP geolocation lookup tool.
“IP geolocation at the country level is one of the most reliable signals on the internet. The 99.5% accuracy means you can confidently build business logic around it. The challenge is not detection — it's implementation.”
Where to resolve the IP: three approaches
The key architectural decision is where in the request lifecycle you perform the IP lookup. Each approach has distinct trade-offs for speed, SEO safety, and implementation complexity.
1. Edge-side (CDN level) — recommended
Modern CDNs like Cloudflare, Vercel, and AWS CloudFront include the visitor's country as a free header on every request. The geolocation lookup happens at the CDN's edge node, typically within 10 milliseconds of the visitor. No external API call, no database to maintain, no latency penalty.
// Cloudflare Worker — redirect by IP-resolved country
export default {
async fetch(request) {
const country = request.cf?.country; // Resolved from IP at the edge
const url = new URL(request.url);
// Only redirect the homepage
if (url.pathname === '/') {
const routes = {
DE: 'https://de.yourstore.com',
FR: 'https://fr.yourstore.com',
JP: 'https://jp.yourstore.com',
BR: 'https://br.yourstore.com',
};
// Skip bots
const ua = request.headers.get('user-agent') || '';
const isBot = /googlebot|bingbot|gptbot|claudebot/i.test(ua);
if (!isBot && routes[country]) {
return Response.redirect(routes[country], 302);
}
}
return fetch(request);
}
};Vercel provides the same data through its Edge Middleware:
// middleware.ts — Next.js Edge Middleware
import { NextRequest, NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
const country = request.geo?.country;
const ua = request.headers.get('user-agent') || '';
const isBot = /googlebot|bingbot|gptbot|claudebot/i.test(ua);
if (!isBot && request.nextUrl.pathname === '/') {
const routes: Record<string, string> = {
DE: 'https://de.yourstore.com',
FR: 'https://fr.yourstore.com',
JP: 'https://jp.yourstore.com',
};
const destination = routes[country ?? ''];
if (destination) {
return NextResponse.redirect(destination, 302);
}
}
return NextResponse.next();
}2. Server-side (application level)
If you run your own server, you can resolve the visitor's IP against a local geolocation database. This requires downloading and periodically updating the MaxMind GeoLite2 database (free, updated weekly).
// Express.js — server-side IP redirect
const maxmind = require('maxmind');
const path = require('path');
// Load the database once at startup
const dbPath = path.resolve('./GeoLite2-Country.mmdb');
const lookup = await maxmind.open(dbPath);
app.use((req, res, next) => {
// Get the real IP behind proxies
const ip = req.headers['x-forwarded-for']?.split(',')[0]
|| req.headers['x-real-ip']
|| req.ip;
const result = lookup.get(ip);
const country = result?.country?.iso_code;
// Skip bots
const ua = req.headers['user-agent'] || '';
if (/googlebot|bingbot|gptbot/i.test(ua)) {
return next();
}
// Check for manual override cookie
if (req.cookies.geo_override) {
return next();
}
const routes = {
DE: '/de/',
FR: '/fr/',
JP: '/ja/',
};
if (routes[country] && req.path === '/') {
return res.redirect(302, routes[country]);
}
next();
});For PHP (WordPress, Laravel, custom sites):
<?php
// PHP — server-side IP redirect using MaxMind
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
$reader = new Reader('/path/to/GeoLite2-Country.mmdb');
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];
$ip = explode(',', $ip)[0]; // Handle proxy chains
try {
$record = $reader->country($ip);
$country = $record->country->isoCode;
} catch (Exception $e) {
$country = null;
}
// Skip bots
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$isBot = preg_match('/googlebot|bingbot|gptbot/i', $ua);
// Check override cookie
$hasOverride = isset($_COOKIE['geo_override']);
$routes = [
'DE' => '/de/',
'FR' => '/fr/',
'JP' => '/ja/',
];
if (!$isBot && !$hasOverride && isset($routes[$country])
&& $_SERVER['REQUEST_URI'] === '/') {
header('Location: ' . $routes[$country], true, 302);
exit;
}
?>Important: When using X-Forwarded-For, always take the first IP in the chain (the client's original IP). Subsequent IPs are proxies. If you use the wrong IP, you'll redirect based on your CDN's location, not the visitor's.
3. Client-side JavaScript (not recommended)
A JavaScript snippet on your page calls a geolocation API, resolves the visitor's IP to a country, and redirects via window.location:
// Client-side IP redirect (NOT recommended)
fetch('https://ipapi.co/json/')
.then(res => res.json())
.then(data => {
const routes = {
DE: 'https://de.yoursite.com',
FR: 'https://fr.yoursite.com',
};
const dest = routes[data.country_code];
if (dest) window.location.href = dest;
})
.catch(() => {
// API blocked or failed — visitor stays on default page
});This approach has well-documented problems:
- Page flicker: The original page loads fully before the redirect fires, causing a visible flash of wrong content.
- Ad blocker interference: According to Backlinko's 2024 report, approximately 32.8% of internet users use an ad blocker. Many ad blockers block requests to third-party IP geolocation APIs, causing the redirect to silently fail.
- Rate limits and costs: Free geolocation APIs like ipapi.co cap at 1,000 requests per day. At scale, you need a paid plan ($12-99/month) just for the API calls.
- SEO risk: Google Search Central warns against using JavaScript-based location detection for redirects. Client-side redirects are invisible to crawlers and can be interpreted as cloaking.
Handling the X-Forwarded-For header correctly
If your application sits behind a load balancer, CDN, or reverse proxy, the visitor's real IP is not req.ip or REMOTE_ADDR — it's in the X-Forwarded-For header. This header can contain multiple IPs separated by commas:
X-Forwarded-For: 203.0.113.50, 70.41.3.18, 150.172.238.178
^ ^ ^
Client IP Proxy 1 IP Proxy 2 IPAlways use the first IP in the chain. Common mistakes include using the last IP (which is often your CDN's IP) or using the entire header as a single string (which will fail the geolocation lookup).
Some CDNs provide their own header for the client IP. Cloudflare uses CF-Connecting-IP, AWS uses X-Forwarded-For (first entry), and Vercel provides x-real-ip. Use the CDN-specific header when available — it's more reliable than parsing X-Forwarded-For yourself.
IPv6 and geolocation accuracy
IPv6 adoption reached 45% globally by early 2025, according to Google's IPv6 statistics. This matters for IP-based redirects because IPv6 geolocation accuracy can differ from IPv4. MaxMind reports that their IPv6 accuracy is within 1-2% of their IPv4 accuracy at the country level, so for country-based redirects, IPv6 is not a concern.
However, if you are parsing IP addresses manually, ensure your code handles both IPv4 (e.g., 203.0.113.50) and IPv6 (e.g., 2001:0db8:85a3::8a2e:0370:7334) formats. Most geolocation libraries handle this automatically.
Five rules for SEO-safe IP redirects
IP-based redirects are a powerful tool, but they interact with search engines in ways that require care. Follow these rules to protect your rankings:
1. Always use 302 redirects
A geo redirect is conditional — different visitors see different destinations. This is the definition of a temporary redirect (302). Using a 301 (permanent) tells search engines the original URL no longer exists, which can cause de-indexing.
2. Bypass bots automatically
Search engine crawlers (Googlebot, Bingbot) and AI crawlers (GPTBot, ClaudeBot, PerplexityBot) should see your default content, not be redirected. This is not cloaking — you are allowing crawlers to index all versions of your content. Use our free bot checker tool to verify how crawlers see your site.
3. Use explicit rules, not exclusion rules
“Redirect visitors FROM Germany to /de/” is safe. “Redirect everyone NOT in the US” is dangerous. Googlebot's IP addresses do not reliably resolve to any specific country, so exclusion rules can accidentally redirect the crawler away from your primary content.
4. Implement hreflang tags
Hreflang tags tell search engines which page version to show in each country's search results. They complement IP redirects: hreflang handles search results, IP redirects handle direct visits. Generate them with our free hreflang generator.
5. Provide a manual override
A German expat in Japan should be able to switch to the German version manually. Always add a region selector that sets a cookie to bypass the automatic redirect.
Special cases: VPNs, proxies, and Tor
IP-based geolocation is imperfect when the visitor's IP does not reflect their actual location:
- VPNs: Approximately 31% of internet users worldwide use a VPN, according to Surfshark's 2023 report. VPN users are redirected based on the VPN server's country, not their own. This is usually acceptable behavior — a US user connecting through a German VPN likely wants the German experience.
- Corporate proxies: Large corporations often route all traffic through a central proxy. Employees in a Tokyo office may appear to be in San Francisco if the corporate proxy is located there. This affects a small percentage of traffic.
- Tor: Tor exit nodes are distributed globally and change frequently. Tor users will be redirected based on the exit node's country, which may change between sessions.
- Mobile networks: Cellular carriers sometimes route traffic through centralized gateways. A mobile user in a rural area may resolve to the nearest city rather than their actual location. This primarily affects city-level targeting, not country-level.
For all these cases, the solution is the same: provide a manual region selector so users can override the automatic redirect. This is a user experience requirement, not just a technical consideration.
Building a region override mechanism
Every IP-based redirect implementation needs an escape hatch. Visitors using VPNs, traveling abroad, or simply preferring a different region should be able to override the automatic redirect. The standard approach is a cookie-based override:
// Region selector — set cookie to override IP redirect
function setRegionOverride(region) {
document.cookie =
`geo_override=${region}; path=/; max-age=${30 * 24 * 60 * 60}; SameSite=Lax`;
// Redirect to the selected region
window.location.href = region ? `/${region}/` : '/';
}
// In your region selector dropdown:
// <button onClick={() => setRegionOverride('de')}>Germany</button>
// <button onClick={() => setRegionOverride('fr')}>France</button>
// <button onClick={() => setRegionOverride('')}>Default (US)</button>Your redirect logic should check for this cookie before performing the IP lookup. If the cookie exists, skip the automatic redirect and serve the region the visitor chose. Place your region selector in a visible location — the header or footer — where users expect to find it.
Platform-specific guides
Different platforms have different constraints for implementing IP-based redirects. We have written dedicated guides for the most popular ones:
- IP redirects for Shopify — script tag integration, Shopify Markets compatibility
- IP redirects for WordPress — plugins vs scripts vs server-side, caching compatibility
- IP redirects for Webflow — adding geo-redirects to a static site builder
For platforms where you do not control the server (Shopify, Webflow, Squarespace), a script tag approach or edge-based service like GeoSwap is the only option for IP-based redirects. Server-side code examples in this guide work on platforms where you have server access (custom apps, WordPress with hosting access, etc.).
The no-code alternative: GeoSwap
If you prefer not to write and maintain redirect code, GeoSwap provides IP-based redirects through a visual dashboard. Add a single script tag to your site, define rules like “visitors from Germany go to /de/”, and publish. The redirects execute at the edge via Cloudflare Workers — the same architecture as the Cloudflare Worker code example above, but managed through a UI.
GeoSwap is free, with no pageview limits or premium tiers. GeoRedirect handles IP-based redirects. GeoContent handles content personalization by location. GeoLink handles geo-targeted short links. All three are included.
Testing IP-based redirects
You cannot verify IP-based redirects from your own location alone. Here are the most reliable testing methods:
- VPN testing: Connect to a VPN server in each target country and visit your site. This simulates a real visitor from that country.
- cURL with headers: Use cURL to test specific scenarios:
# Test redirect response from a specific IP
curl -I -H "X-Forwarded-For: 185.86.151.11" https://yoursite.com
# Expected output for a German IP:
# HTTP/2 302
# location: https://de.yoursite.com- GeoSwap preview mode: The GeoSwap dashboard includes a preview mode that simulates visits from any country without needing a VPN.
- Redirect checker: Use our free redirect checker tool to verify the HTTP status code and redirect destination of any URL.
For a comprehensive testing guide covering six methods, see our guide to testing your website from another country.
Performance benchmarks
The speed of your IP redirect depends entirely on where the lookup happens:
| Method | Lookup time | Page flicker | Works on static sites |
|---|---|---|---|
| Edge (Cloudflare Workers) | Under 10ms | No | Yes |
| Server-side (local DB) | 1-5ms + server RTT | No | No |
| Server-side (API call) | 50-200ms + server RTT | No | No |
| Client-side JavaScript | 200-500ms after page load | Yes | Yes |
| GeoSwap (edge, no-code) | Under 10ms | No | Yes |
Frequently asked questions
Is it legal to redirect users based on their IP address?
Yes. IP-based geo-targeting is legal in all major jurisdictions. Under GDPR, IP addresses are considered personal data, but using them for geolocation (without storing them) falls under the “legitimate interest” basis. Disclose the practice in your privacy policy.
What geolocation database should I use?
For self-hosted solutions, MaxMind GeoLite2 is the standard. It is free, updated weekly, and provides 99.5% country-level accuracy. For edge solutions, use the built-in CDN headers (Cloudflare's cf-ipcountry, Vercel's request.geo) — they use the same underlying data without you maintaining a database.
How often do I need to update the geolocation database?
MaxMind updates GeoLite2 weekly. IP allocations change as ISPs acquire and release IP blocks. Running a database more than a month old can introduce inaccuracies. Set up a cron job to pull updates automatically. If you use an edge-based solution like GeoSwap, the database is managed for you.
Can I redirect based on state or city, not just country?
Yes. Country-level detection is 99.5% accurate, state-level is 80-90%, and city-level is 70-80%. For state-level use cases (showing different content for California vs Texas), GeoSwap's GeoRedirect supports country, state, and city-level targeting.
What happens if the IP lookup fails?
Always define a fallback. If the geolocation lookup returns no result (which happens with some satellite internet providers and very new IP allocations), serve your default content. Never redirect to an error page or leave the visitor with a broken experience.
Should I store the visitor's country in a cookie?
Yes. After the first IP lookup, set a cookie with the resolved country (or the user's manual override). On subsequent requests, check the cookie first to avoid redundant lookups and to respect manual overrides. Use a 30-day expiration and the SameSite=Lax attribute.
IP-based redirects are the most reliable way to route visitors to the right content for their location. Edge-side execution gives you the best combination of speed, accuracy, and SEO safety. Whether you build it yourself with Cloudflare Workers or use GeoSwap's no-code solution, follow the five rules in this guide — 302 redirects, bot bypass, explicit rules, hreflang tags, and manual overrides — and your international visitors will land exactly where they belong.
