typescriptintermediate

Edge Middleware Geolocation

Use Vercel Edge geolocation headers to personalize content based on the visitor's country and city.

typescript
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  const country = request.headers.get('x-vercel-ip-country') ?? 'US';
  const city = request.headers.get('x-vercel-ip-city') ?? 'Unknown';
  const region = request.headers.get('x-vercel-ip-country-region') ?? '';

  const response = NextResponse.next();

  // Pass geo data to pages via headers
  response.headers.set('x-geo-country', country);
  response.headers.set('x-geo-city', decodeURIComponent(city));
  response.headers.set('x-geo-region', region);

  // Example: redirect EU users to GDPR consent page
  const EU_COUNTRIES = [
    'AT','BE','BG','HR','CY','CZ','DK','EE','FI','FR',
    'DE','GR','HU','IE','IT','LV','LT','LU','MT','NL',
    'PL','PT','RO','SK','SI','ES','SE',
  ];

  if (
    EU_COUNTRIES.includes(country) &&
    !request.cookies.get('gdpr-consent') &&
    !request.nextUrl.pathname.startsWith('/consent')
  ) {
    return NextResponse.redirect(new URL('/consent', request.url));
  }

  return response;
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};

Use Cases

  • GDPR consent flows
  • Localized pricing
  • Regional content delivery

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.