Skip to content

Instantly share code, notes, and snippets.

@Praveenkumar07007
Last active December 7, 2025 08:46
Show Gist options
  • Select an option

  • Save Praveenkumar07007/b003ed760a21215b541c59b3756bf345 to your computer and use it in GitHub Desktop.

Select an option

Save Praveenkumar07007/b003ed760a21215b541c59b3756bf345 to your computer and use it in GitHub Desktop.
MAP

there is no “perfect auto-detect location” button

Browsers and servers don’t magically know the user’s exact location.

You really only have two serious options:


A) GPS-based (Browser Geolocation API)

This is the one everyone thinks of:

  • Runs in the browser
  • Uses the device’s GPS / Wi-Fi / network
  • Shows a permission popup to the user

Example output:

{ "lat": 28.6139, "lng": 77.2090 }

You can then hit your backend with that and query for nearby stores.

Pros

  • Very accurate (street or building level)
  • Good for “nearest store” / “delivery in 10 mins” style apps

Cons

  • User might click “Block” and then you’re done
  • Only works on the client (no use for SSR/SEO on first load)
  • Not ideal to trigger on page load, or users bounce

B) IP-based Geolocation

This is the server-side friendly version.

  • Uses the user’s IP to guess location
  • Works before the page renders (SSR / Edge)
  • Accuracy is more like city or region, not street

You usually plug in a provider:

  • MaxMind
  • IP2Location
  • IPinfo
  • Cloudflare Geo headers
  • Vercel Edge Geo (if you deploy on Vercel)

Pros

  • No permission popup
  • Works on first page load
  • Great for SEO and initial experience
  • Good enough to say “show stores in Delhi” or “Mumbai”

Cons

  • Not precise enough for “nearest store is 450m away”
  • VPN / proxies can mess it up
  • Sometimes guessed city is wrong

What actually makes sense in production (2025 mindset)

The sane, production-style flow is:

Step 1: Use IP-based detection on the server

  • Figure out country / region / city from IP
  • Based on that, pick local stores or inventory
  • Render page with those recommendations already there

So users see something relevant instantly.

Then:

Step 2: Ask for GPS only if necessary

  • If they want super accurate “near me” results
  • Or when they tap a button like “Use current location”

This is close to how Zomato, Swiggy, Blinkit, Instamart, etc. do it:

  • Coarse location from IP for defaults
  • Precise location only when user is clearly interested

Next.js implementation (high-level, but real)

1. Use Middleware or Route Handler (Vercel)

On Vercel, you get geo injected into the request at the Edge.

src/middleware.ts:

import { NextResponse } from "next/server";

export function middleware(req: Request) {
  // Available on Vercel Edge
  const geo = (req as any).geo;

  return NextResponse.next({
    headers: {
      "x-country": geo?.country || "",
      "x-region": geo?.region || "",
      "x-city": geo?.city || "",
      "x-latitude": geo?.latitude || "",
      "x-longitude": geo?.longitude || ""
    }
  });
}

This middleware:

  • Runs before your route
  • Reads geo info
  • Attaches it as headers for your app to use

2. Use those headers in your server logic

Example idea (pseudo-ish):

export default async function Page({ req }: { req: Request }) {
  const city = req.headers.get("x-city");
  const lat  = req.headers.get("x-latitude");
  const lng  = req.headers.get("x-longitude");

  const stores = await getNearbyStores({ lat, lng });

  return <StoreList stores={stores} />;
}

Flow:

  1. Middleware adds geo headers
  2. Server component / API handler reads them
  3. You fetch stores close to that location
  4. Page loads with localized data from the first render

(Exact access to req depends on whether you’re using App Router / Pages Router / Route Handlers, but concept is the same.)


Not on Vercel? No problem.

Then you just do IP lookup yourself on the server.

Example:

const ip = req.headers["x-forwarded-for"] || req.socket.remoteAddress;

// Call IP provider
const res = await fetch(`https://ipinfo.io/${ip}?token=YOUR_TOKEN`);
const data = await res.json();

// Example: "28.6139,77.2090"
const [lat, lng] = data.loc.split(",");

Use lat and lng from here to do:

  • “Stores near user city”
  • “Default city selection”
  • “Top products around you”

Optional upgrade: Browser Geolocation (fine-tuning)

On the client, when user clicks a button like “Use my location”:

navigator.geolocation.getCurrentPosition(pos => {
  const { latitude, longitude } = pos.coords;

  fetch("/api/geo", {
    method: "POST",
    body: JSON.stringify({ latitude, longitude })
  });
});

Best practices

  • Do not ask for GPS the moment the page loads
  • Ask only after intent: user clicks “Use current location”
  • Explain why: “We’ll show you the closest store and delivery time”

Users are way more likely to accept it when it’s contextual.


Recommended architecture

Server (IP-based, automatic)

  • Detect location roughly (city/region)
  • Show reasonable defaults for local catalog
  • Good for SEO and first impression

Client (GPS, opt-in)

  • Show a button: “Use precise location”

  • When user taps:

    • Request geolocation
    • Hit backend with coordinates
    • Return truly nearest stores / slots / offers

This is the balance between UX and not being creepy/annoying.


Security & privacy reality check

You cannot play dumb here.

  • Don’t store precise coordinates unless you actually need them

  • If you store, say why and for how long

  • Be careful logging things like:

    • Access logs with full GPS
    • Debug logs with user coordinates

You are in the territory of GDPR, CCPA, etc. so treat location data as sensitive.


What you should absolutely avoid

Here’s how people mess this up:

  • Blocking the UI waiting for GPS on first load
  • Triggering location permission immediately when page opens
  • Sending raw lat/lng in query params everywhere
  • Dumping thousands of stores to client and filtering there
  • Building the whole location logic only on client (bad SEO + bad initial UX)

Tech stack that fits well with Next.js

Purpose Option
Server IP lookup Vercel Geo / IPinfo / MaxMind
Map / UI Google Maps / Mapbox
Store distance Haversine formula / PostGIS

You don’t have to go overboard on day 1, but this is the direction.


Simple geospatial query (Postgres example)

If you use Postgres + PostGIS:

SELECT id, name,
  ST_Distance(
    geography(ST_Point(lng, lat)),
    geography(ST_Point($lng, $lat))
  ) AS distance
FROM stores
ORDER BY distance
LIMIT 10;

This gives you nearest stores by distance from given coordinates.


TL;DR – sane, high-UX approach

If you want solid UX and not annoy users:

  1. IP-based geo on the server

    • Detect city/region automatically
    • Render page with local products
  2. Button to enable precise GPS

    • “Show nearest store”
    • Use Geolocation API only when user asks
  3. Cache aggressively

    • Same city → same recommendations for many users
    • Use CDN and edge caching

This is more or less what serious consumer apps do.


For Next.js specifically

Sweet spot:

  • Deploy on Vercel
  • Use Vercel Edge Geo
  • Add middleware to inject headers
  • Use server components / route handlers
  • Use DB with geospatial support (PostGIS, Mongo with 2dsphere, etc.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment