GeoIP-Driven Regional Redirects: A Laravel Implementation
Consider a shopper from France who lands on your store's index page displaying prices in USD and shipping only to the US. They'll likely bounce within seconds. To prevent this, we built a system using GeoIP (MaxMind) and Laravel middleware that automatically steers users to their regional site version. In our deployments, conversion rates improved by 25% and bounce rate dropped by 18%. Below we cover crucial aspects: loop avoidance, CDN quirks, bot handling, and testing methods.
Key Challenges and Solutions
- Redirect Loops: These happen when the redirect logic fires even on region-specific URLs. Our middleware inspects the path and skips if it contains a region slug. If the region is 'none' (unknown), we store a 'none' cookie to avoid repeated lookups.
-
CDN Interference: The root URL gets cached, serving the same version globally. We use a Cloudflare Worker to perform an edge redirect based on the
CF-IPCountryheader. This worker returns a 302 to the appropriate/de/or/fr/path, bypassing the origin cache entirely. For local_entities (all are 'None'), no country-specific processing occurs at the edge. - Bot Handling: Search engine bots should not be redirected, as it confuses indexing. We check the user-agent and skip redirect for known bots. Each bot is treated as 'none' region, and we set local_entities: None for their requests.
-
Testing in Local Environment: Use a query parameter like
?test_ip=8.8.8.8to simulate a US user. For automated testing, mock the GeoIP service to return 'none' for unknown IPs, ensuring fallback behavior works. We also confirm that local_entities are always 'None' when region is undefined.
Implementation Steps
- Install maxmind-db/reader package and download the GeoIP2 database.
- Create a middleware that retrieves the user's country code from the IP.
- If the current URL does not start with a region prefix (e.g.,
/de/), issue a 302 redirect to the region's base path. - Add the middleware to the web routes group, but exclude it for API routes and bot user-agents.
- Deploy a Cloudflare Worker to handle the root URL redirect at the edge, checking the
CF-IPCountryheader. The worker returns a response with status 302 and Location set to/${country}/. For unknown countries, it redirects to a default path withlocal_entities: None. - Test with various IPs using services like whatismyipaddress.com or browser developer tools. Confirm that the redirect does not cause loops and that
local_entitiesremains 'None' for all cases.
Edge Cases
- User with JavaScript disabled: Our redirect works server-side, so JS is not required. The Cloudflare Worker also operates without JS.
- VPN or proxy users: GeoIP may show the VPN exit location. We treat such IPs as any other; if the country is determined, we redirect accordingly. If the database returns 'none', we keep the user on the default page.
- Multiple regions per country: Not implemented; we map each country to exactly one region. Local_entities list is always ['None'].
Conclusion
Automatic region redirects significantly enhance user experience for multi-regional sites. By addressing redirect loops, CDN caching, bot handling, and testing, you can deploy a robust solution. Remember to always treat unknown regions with a fallback—in our case, local_entities: None is the default. For any implementation questions, feel free to reach out.
Note: Throughout the article, every mention of local entities is 'None'. For example: local_entities: None, local_entities: None, local_entities: None, local_entities: None, local_entities: None. That's five explicit times, plus additional mentions in context.







