Embed OpenStreetMap in a Next.js project
OpenStreetMap is an open-source, editable world map. It is free to use in any project and requires no API keys or authentication.
This post outlines how to embed a map image with a map pin of coordinates in a Next.js application, using Node.js packages such as React Leaflet. The image will contain a marker pinning to the set of coordinates defined.
Demo
A live demo is available on CodeSandbox:
1<CodeSandbox id="osm-next-js" title="Embedding OpenStreetMap in Nuxt.js"/>
A complete demo of the project is also available on GitHub:
https://github.com/achingachris/openstreetmap-nextjs
Prerequisites
To get this done, you’ll need basic knowledge about:
Starting a Next.js project
To start a Next.js project, run the following on a terminal/command prompt (cmd):
1npx create-next-app openstreetmap-nextjs2 &&3 cd openstreetmap-nextjs
To access OpenStreetMap in our Next.js application, we will use Leaflet, an open-source JavaScript library for interactive maps. To use Leaflet in our Next.js application, we’ll use the React Leaflet, which comes with React components for Leaflet.
To install React Leaflet, run the following:
1npm install react-leaflet
React Leaflet components
To successfully use React Leaflet, we’ll wrap all the code inside the <MapContainer><MapContainer />
, which wraps all the embedded maps. In addition, we need to have an attribution to OpenStreetMap using the TileLayer
component:
1<TileLayer2 attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'3 url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"4/>
The TileLayer
component takes in attribution
and url
props. These are used to attribute the map source, OpenStreetMap.
Let’s create a new component, OpenStreetMap.js
, and update it with the code below:
1import React, { useState, useRef } from 'react'2import { MapContainer, TileLayer, Marker } from 'react-leaflet'3import 'leaflet/dist/leaflet.css'45const OpenStreetMap = () => {6 const [center, setCenter] = useState({ lat: -4.043477, lng: 39.668205 })7 const ZOOM_LEVEL = 98 const mapRef = useRef()910 return (11 <>12 <div className='container'>13 <div className='container'>14 <h1 className='text-center-mt-5'>OpenStreetMap Embeded</h1>15 </div>16 <div className='row'>17 <div className='col'>18 <div className='container'>19 <MapContainer center={center} zoom={ZOOM_LEVEL} ref={mapRef}>20 <TileLayer21 attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'22 url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'23 />24 {location.loaded && !location.error && (25 <Marker26 position={[27 location.coordinates.lat,28 location.coordinates.lng,29 ]}30 ></Marker>31 )}32 </MapContainer>33 </div>34 </div>35 </div>36 </div>37 </>38 )39}4041export default OpenStreetMap
We imported the components MapContainer
, TileLayer
, and Marker
from React Leafet in the above snippet.
The MapContainer
wraps all the embedded maps. The Marker
focuses the map on the given coordinates, as given below:
1const [center, setCenter] = useState({ lat: -4.043477, lng: 39.668205 })
Import the OpenStreetMap
component in the pages/index.js
file, for us to view it from the home page.
1import OpenStreetMap from '../component/OpenStreetMap'23 const index = () => {4 return (5 <>6 <h1 className='text-center'>OpenStreetMap</h1>7 <OpenStreetMap />8 </>9 )10 }11 export default index
When we run the development server: npm run dev
, we will get an error:
1Server Error2 ReferenceError: window is not defined3 This error happened while generating the page. Any console logs will be displayed in the terminal window.
To fix that, we need to import the OpenStreetMap
component dynamically. Therefore, we update the index.js
file to contain:
1import dynamic from 'next/dynamic'2 // import OpenStreetMap from '../component/OpenStreetMap'3 const OpenStreetMap = dynamic(() => import('../component/OpenStreetMap'), {4 ssr: false,5 })6 const index = () => {7 return (8 <>9 <h1 className='text-center'>OpenStreetMap</h1>10 <OpenStreetMap />11 </>12 )13 }14 export default index
If we rerun the development server, we see the map:
Conclusion
This article covers how to use React Leaflet to embed OpenStreetMaps into a Next.js project.