Use case · Geo-targeting

Localise from the first byte.

Every visitor hits your origin with an IP. Resolve it once at the edge, cache it, and ship the right currency, language, and legal banners before your React bundle finishes parsing.

Fields you need

FieldUse
countryCurrency, legal banners (GDPR, CCPA), regional pricing
country_nameHuman-readable "shipping to Germany"
regionUS state for sales-tax routing; EU region for VAT
timezone"Delivery at 3pm your time" instead of "3pm UTC"

Cloudflare Worker pattern (recommended)

At the CDN edge, look up the visitor IP once per session and cache the result in a signed cookie. Your origin never pays the RTT.

// Cloudflare Worker — geo-cookie
export default {
  async fetch(req, env) {
    const cookie = getCookie(req, 'ipa_geo');
    if (cookie) return fetch(req, { cf: { cookie } });

    const ip = req.headers.get('cf-connecting-ip');
    const r  = await fetch(`https://api.ip-atlas.io/json/${ip}`, {
      headers: { 'X-API-Key': env.IPATLAS_KEY }
    }).then(r => r.json());

    const res = await fetch(req);
    res.headers.append('Set-Cookie',
      `ipa_geo=${r.country}; Max-Age=86400; Path=/; Secure`);
    return res;
  }
};

Next.js middleware pattern

// middleware.ts
export async function middleware(req) {
  const ip = req.ip;
  const r  = await fetch(`https://api.ip-atlas.io/json/${ip}`, {
    headers: { 'X-API-Key': process.env.IPATLAS_KEY! }
  }).then(r => r.json());
  const res = NextResponse.next();
  res.cookies.set('country', r.country, { maxAge: 86400 });
  res.cookies.set('tz', r.timezone, { maxAge: 86400 });
  return res;
}

What NOT to do