10 / 10

How would you implement geo-based routing (serve different content by country) using middleware?

Geo-based routing in Next.js is implemented using Middleware which has access to the request's geo data (country, region, city) via request.geo on Vercel, or via third-party IP geolocation on self-hosted deployments. Middleware intercepts the request at the Edge and rewrites or redirects to country-specific pages — all before any HTML is rendered.

Geo-based routing is one of the most powerful use cases for Next.js Middleware. Because middleware runs at the Edge — physically close to the user — it can detect the user's location and make routing decisions with near-zero latency. The key distinction is between a rewrite (URL stays the same, different content served) and a redirect (URL changes to country-specific URL). Most production apps use rewrites for seamless UX and redirects for explicit locale routing.

Geo Data Available in Middleware
  1. 1

    request.geo.country — ISO 3166-1 alpha-2 country code (e.g. 'US', 'GB', 'DE')

  2. 2

    request.geo.region — region/state code (e.g. 'CA' for California)

  3. 3

    request.geo.city — city name (e.g. 'San Francisco')

  4. 4

    request.geo.latitude — latitude coordinate

  5. 5

    request.geo.longitude — longitude coordinate

  6. 6

    request.ip — user IP address (for manual geolocation lookup)

  7. 7

    geo data is provided by Vercel automatically — self-hosted needs manual IP lookup

Basic Geo-Based Rewrite — Same URL, Different Content
Geo-Based Redirect — URL Changes to Country-Specific Path
Respecting User Country Preference (Cookie Override)
Country-Specific Content Pages Structure
Geo-Blocking — Restrict Access by Country
Self-Hosted — Manual IP Geolocation (No Vercel)
Passing Geo Data to Server Components
Rewrite vs Redirect for Geo Routing
  1. 1

    Rewrite — URL stays the same (/pricing), different page renders — best for seamless UX

  2. 2

    Rewrite — SEO sees one URL — simpler canonical URL management

  3. 3

    Rewrite — user cannot share country-specific URL — always gets geo-detected version

  4. 4

    Redirect — URL changes to /en-gb/pricing — explicit, shareable, bookmarkable

  5. 5

    Redirect — better for i18n and multi-locale SEO with hreflang tags

  6. 6

    Redirect — user can manually navigate to a different country URL

  7. 7

    Best practice — use rewrite for invisible geo content swaps, redirect for explicit locale routing

Key Takeaways
  1. 1

    request.geo is available automatically on Vercel — no setup needed

  2. 2

    Self-hosted deployments need manual IP geolocation via third-party service or Cloudflare headers

  3. 3

    Always provide a fallback country — geo detection can fail or return null

  4. 4

    Use cookies to let users override geo detection — respect user preference over auto-detection

  5. 5

    Inject country into request headers so Server Components can access geo data without re-detecting

  6. 6

    Pre-build all country variants with generateStaticParams for maximum performance

  7. 7

    Exclude _next/static and public assets from middleware matcher to avoid unnecessary processing

  8. 8

    Use rewrites for invisible content swaps and redirects for explicit locale-based URL structures