close button
How to Integrate Maps on your Web pages Using react-leaflet on next.js
mohammedkhan.png Mohammed khan
4 min read Nov 17, 2025

How to Integrate Maps on your Web pages Using react-leaflet on next.js

unnamed-11.png

So, if you’ve landed here, chances are you’re either on the hunt for some open-source map magic or you’ve already checked Google Maps API pricing 😅

Let’s be honest, paying for maps when your app starts getting traffic can feel like watching your wallet slowly catch fire. That’s why in this post, I’m going to show you how to integrate **interactive maps in Next.js using React-Leaflet **completely free of cost. No surprise bills, no crying over usage limits.

Why React-Leaflet + OpenStreetMap?

  • Leaflet → a lightweight, open-source JavaScript library for maps.
  • React-Leaflet → a React wrapper around Leaflet, making it easy to use with React and Next.js.
  • OpenStreetMap (OSM) → free, community-driven map tiles you can use without worrying about hidden costs.

Together, these tools give you all the flexibility of Google Maps without the price tag.

Getting Started with the Project

You could use React with React-Leaflet, and everything would work just fine. But for this example, I’m using Next.js

//Now, install the required dependencies:

npm install react-leaflet@next

npm install -D @types/leaflet

  • react-leaflet@next → the latest version that supports React and Next.js
  • @types/leaflet → type definitions for TypeScript.

Building the Map Component

Inside your project, create a Map.tsx file under src/app/components/

React-Leaflet doesn’t support SSR due to Leaflet construction, according to its documentation there’re limitations that’s why we use the directrice "use client" in our Map component

Leaflet makes direct calls to the DOM when it is loaded, therefore React Leaflet is not compatible with server-side rendering.
"use client";

import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import { LatLngExpression, LatLngTuple } from "leaflet";

import "leaflet/dist/leaflet.css";
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
import "leaflet-defaulticon-compatibility";

interface MapProps {
 posix: LatLngExpression | LatLngTuple;
 zoom?: number;
}

const defaults = {
 zoom: 19,
};

const Map = ({ zoom = defaults.zoom, posix }: MapProps) => {
 return (
   <MapContainer
     attributionControl={false}
     center={posix}
     zoom={zoom}
     scrollWheelZoom={false}
     style={{ height: "100%", width: "100%" }}
   >
     <TileLayer
       attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
       url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
     />
     <Marker position={posix} draggable={false}>
       <Popup>Hey, I'm a popup!</Popup>
     </Marker>
   </MapContainer>
 );
};

export default Map;


### MapContainer
  • Think of it as the root component that sets up the Leaflet map instance. It’s required because it initializes and manages the lifecycle of the map.
  • Props you pass here (like center, zoom, scrollWheelZoom) configure the map itself. Without this, no map is rendered.

<MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={false} />



### TileLayer
  • Leaflet by itself is just a mapping engine it needs a tile provider (like Google Maps, OpenStreetMap, Mapbox) to actually display the map.
  • TileLayer tells the map where to fetch tiles from. The url prop is where you provide the tile source (here: OpenStreetMap is given).
  • The attribution is legally required for most providers.

<TileLayer

url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"

attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'

/>



### Marker
  • Used to place a pin / point of interest on the map at a given latitude & longitude.
  • By default, it uses the classic Leaflet blue pin icon (unless overridden). You can make it draggable or static.
  • Needs a position prop → the lat/long coordinates.

<Marker position={[51.505, -0.09]} />



### Popup
  • A small overlay window that appears when you click on a marker (or other supported map elements).
  • Typically used to show details about that location. Can contain plain text or React components.

<Marker position={[51.505, -0.09]}>

<Popup>Hello! I'm a popup.</Popup>

</Marker>

Rendering the Map in a Next.js Page

As a SSR component our page can’t handle with map importing by default that would produce an error, so we can use dynamic from Next to import a component “turning off” the SSR strategy

"use client";

import dynamic from "next/dynamic";

const Map = dynamic(() => import("@/app/components/Map"), { ssr: false });

export default function Home() {
 return (
   <div className="bg-amber-100 mx-auto my-5 w-[98%] h-[480px]">
     <Map posix={[12.995218768575647, 77.5548894807005]} />
   </div>
 );
}

And that’s it — you’ve just added a fully functional, open-source map to your Next.js app without touching Google Maps. If you’re not worried about pricing, you can also play around with different tile layers such as Mapbox, MapTiler, or even Google Maps.

🔗 GitHub Repository

Want to skip the setup and try it out directly? Here’s the full code on GitHub:

👉 GitHub Project Link

Application Modernization Icon

Unleash your brand's potential with AntStack Design, our dedicated UI/UX team. Experience design solutions that embody your vision, resonate with your audience, and drive growth. Embark on a transformative design journey tailored to your startup's unique needs.

Talk to us

Tags

Your Digital Journey deserves a great story.

Build one with us.

Recommended Blogs

Cookies Icon

These cookies are used to collect information about how you interact with this website and allow us to remember you. We use this information to improve and customize your browsing experience, as well as for analytics.

If you decline, your information won’t be tracked when you visit this website. A single cookie will be used in your browser to remember your preference.