Skip to content

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.

A live demo is available on CodeSandbox:

    

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:


- [React.js](https://reactjs.org/)/[Next.js](https://nextjs.org/)
- [OpenStreetMap](https://www.openstreetmap.org/)
# Starting a Next.js project

To start a Next.js project, run the following on a terminal/command prompt (cmd):

```poweshell
    npx create-next-app openstreetmap-nextjs
    &&
    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:

    npm install react-leaflet

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:

<TileLayer
    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
Code language: HTML, XML (xml)

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:

import React, { useState, useRef } from 'react'
import { MapContainer, TileLayer, Marker } from 'react-leaflet'
import 'leaflet/dist/leaflet.css'

const OpenStreetMap = () => {
  const [center, setCenter] = useState({ lat: -4.043477, lng: 39.668205 })
  const ZOOM_LEVEL = 9
  const mapRef = useRef()

  return (
    <>
      <div className='container'>
        <div className='container'>
          <h1 className='text-center-mt-5'>OpenStreetMap Embeded</h1>
        </div>
        <div className='row'>
          <div className='col'>
            <div className='container'>
              <MapContainer center={center} zoom={ZOOM_LEVEL} ref={mapRef}>
                <TileLayer
                  attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                  url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
                />
                {location.loaded && !location.error && (
                  <Marker
                    position={[
                      location.coordinates.lat,
                      location.coordinates.lng,
                    ]}
                  ></Marker>
                )}
              </MapContainer>
            </div>
          </div>
        </div>
      </div>
    </>
  )
}

export default OpenStreetMap
Code language: JavaScript (javascript)

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:

    const [center, setCenter] = useState({ lat: -4.043477, lng: 39.668205 })
Code language: JavaScript (javascript)

Import the OpenStreetMap component in the pages/index.js file, for us to view it from the home page.

    import OpenStreetMap from '../component/OpenStreetMap'
    
    const index = () => {
      return (
        <>
          <h1 className='text-center'>OpenStreetMap</h1>
          <OpenStreetMap />
        </>
      )
    }
    export default index
Code language: JavaScript (javascript)

When we run the development server: npm run dev, we will get an error:

    Server Error
    ReferenceError: window is not defined
    This error happened while generating the page. Any console logs will be displayed in the terminal window.
Code language: JavaScript (javascript)

To fix that, we need to import the OpenStreetMap component dynamically. Therefore, we update the index.js file to contain:

    import dynamic from 'next/dynamic'
    // import OpenStreetMap from '../component/OpenStreetMap'
    const OpenStreetMap = dynamic(() => import('../component/OpenStreetMap'), {
      ssr: false,
    })
    const index = () => {
      return (
        <>
          <h1 className='text-center'>OpenStreetMap</h1>
          <OpenStreetMap />
        </>
      )
    }
    export default index
Code language: JavaScript (javascript)

If we rerun the development server, we see the map:

This article covers how to use React Leaflet to embed OpenStreetMaps into a Next.js project.

Back to top

Featured Post