OWolf

BlogToolsProjectsAboutContact
© 2025 owolf.com
HomeAboutNotesContactPrivacy

2025-06-12 Web Development, Technology

Tracking User Location in React with the Geolocation API

By O. Wolfson

Getting location...

🗺️ Displaying User Location on a Map with Leaflet

Adding real-time maps to your Next.js application can make your user experience more engaging and location-aware. With the HTML5 Geolocation API and the Leaflet mapping library, it's straightforward to display the user's current location on an interactive map.

🧭 What We're Building

We'll build a React component that:

  • Uses the Geolocation API to get the user's location
  • Renders a Leaflet map centered on that location
  • Places a marker at the user's position

🧩 UserLocationMap.tsx

tsx
"use client";

import { useEffect, useState } from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import L from "leaflet";

// Fix missing marker icon in Leaflet
import markerIcon2x from "leaflet/dist/images/marker-icon-2x.png";
import markerIcon from "leaflet/dist/images/marker-icon.png";
import markerShadow from "leaflet/dist/images/marker-shadow.png";

// Set default marker icon
delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
  iconUrl: markerIcon.src,
  iconRetinaUrl: markerIcon2x.src,
  shadowUrl: markerShadow.src,
});

type Position = {
  lat: number;
  lng: number;
};

export default function UserLocationMap() {
  const [position, setPosition] = useState<Position | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!("geolocation" in navigator)) {
      setError("Geolocation is not supported by your browser.");
      return;
    }

    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setPosition({
          lat: pos.coords.latitude,
          lng: pos.coords.longitude,
        });
      },
      (err) => {
        setError(`Error: ${err.message}`);
      },
      {
        enableHighAccuracy: true,
        timeout: 10000,
        maximumAge: 0,
      }
    );
  }, []);

  return (
    <div className="h-[400px] w-full">
      <h2 className="text-lg font-semibold mb-2">Your Location on Map</h2>
      {error && <p className="text-red-500">{error}</p>}
      {position ? (
        <MapContainer
          center={position}
          zoom={13}
          scrollWheelZoom={true}
          className="h-full w-full rounded shadow"
        >
          <TileLayer
            attribution='&copy; <a href="https://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
          <Marker position={position}>
            <Popup>You are here</Popup>
          </Marker>
        </MapContainer>
      ) : !error ? (
        <p>Fetching location and loading map…</p>
      ) : null}
    </div>
  );
}

🧪 Usage in a Next.js Page

tsx
import dynamic from "next/dynamic";

// Dynamically import Leaflet (it uses window object, so SSR must be disabled)
const UserLocationMap = dynamic(() => import("@/components/UserLocationMap"), {
  ssr: false,
});

export default function Page() {
  return (
    <main className="p-6 max-w-2xl mx-auto">
      <UserLocationMap />
    </main>
  );
}

📦 Installation Requirements

To use this in your project, install the required packages:

bash
npm install leaflet react-leaflet

You may also need to configure your Next.js project to handle image imports. If you're using Webpack, this is typically handled automatically. In a Next.js app with the App Router, it should work without changes if you're using Next 13.4+.


🔐 A Note on Privacy

Always request location data responsibly. The user must grant permission, and their data should never be shared without explicit consent.