DEV Community

Abir Ahmed for LogiQbits

Posted on

Creating Interactive Maps with React and Mapbox GL JS in a NextJs App

#Introduction:

Maps are powerful tools for visualizing and exploring geographic data. With the rise of web technologies, it has become easier than ever to create interactive maps within web applications. In this blog post, we will explore how to create interactive maps using React and the Mapbox GL JS library in a NextJs app.

#Setting up the Project To begin:

1.Create a New React Project: Use the following command to create a new NextJs app named "nextjs-mapbox":

npx create-next-app nextjs-mapbox
Enter fullscreen mode Exit fullscreen mode

2.Install Dependencies: Navigate into the project directory and install the required dependencies:

cd nextjs-mapbox
npm install mapbox-gl react
Enter fullscreen mode Exit fullscreen mode

3.Mapbox Access Token: Obtain a Mapbox access token by creating a free account on the Mapbox website. Generate an access token in your Mapbox account dashboard.

4.Environment Variable Setup: In the project's root directory, create a new file named .env.local and add the following line, replacing "your-access-token" with your actual Mapbox access token:

REACT_APP_MAPBOX_ACCESS_TOKEN=your-access-token
Enter fullscreen mode Exit fullscreen mode

#Integrating Mapbox GL JS with React in Next.js:
Create a new file called Map.jsin the components folder with the following code:

import React, { useRef, useEffect, useState } from "react";
import mapboxgl from "mapbox-gl";
import geoJson from "../chicago-parks.json";

const Map = () => {
  const mapContainerRef = useRef(null);
  const [zoom, setZoom] = useState(9);
  const [lng, setLng] = useState(-87.65);
  const [lt, setLt] = useState(41.84);

  useEffect(() => {
    mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_ACCESS_TOKEN;

    const map = new mapboxgl.Map({
      container: mapContainerRef.current,
      style: "mapbox://styles/mapbox/streets-v11",
      center: [lng, lt],
      zoom: zoom
    });

    // Map initialization code goes here

    return () => map.remove();
  }, []);

  return (
    <div>
      <div className="sidebar">
        Longitude: {lng} | Latitude: {lt} | Zoom: {zoom}
      </div>
      <div className="map-container" ref={mapContainerRef} />
    </div>
  );
};

export default Map;

Enter fullscreen mode Exit fullscreen mode

In this code snippet, we import the necessary dependencies and create a React component called Map. Inside the component, we define state variables using the useState hook to hold the current zoom level, longitude, and latitude of the map. The useRef hook is used to create a reference to the map container element.
The useEffect hook is where we initialize the map when the component mounts. We set the Mapbox access token, create a new map instance, and pass in the container reference, style, center coordinates, and initial zoom level. Finally, we update the state variables when the map moves and remove the map instance when the component is unmounted.

#Adding Custom Markers and Line Overlay:
Update the useEffect hook inside the Map component with the following code:

// Inside the useEffect hook
map.on("load", function () {
  map.loadImage(
    "https://docs.mapbox.com/mapbox-gl-js/assets/custom_marker.png",
    function (error, image) {
      if (error) throw error;
      map.addImage("custom-marker", image);

      map.addSource("points", {
        type: "geojson",
        data: {
          type: "FeatureCollection",
          features: geoJson.map((point) => ({
            type: "Feature",
            geometry: {
              type: "Point",
              coordinates: [point.long, point.lat]
            },
            properties: {
              title: `Point ${point.c + 1}`
            }
          }))
        }
      });

      map.addSource("line", {
        type: "geojson",
        data: {
          type: "Feature",
          properties: {},
          geometry: {
            type: "LineString",
            coordinates: geoJson.map((point) => [point.long, point.lat])
          }
        }
      });

      map.addLayer({
        id: "points",
        type: "symbol",
        source: "points",
        layout: {
          "icon-image": "custom-marker",
          "text-field": ["get", "title"],
          "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
          "text-offset": [0, 1.25],
          "text-anchor": "top"
        }
      });

      map.addLayer({
        id: "line",
        type: "line",
        source: "line",
        layout: {},
        paint: {
          "line-color": "blue",
          "line-width": 2
        }
      });
    }
  );
});

Enter fullscreen mode Exit fullscreen mode

In this code snippet, we add custom markers and a line overlay to the map. We use the map.on("load") event listener to ensure the map is fully loaded before adding the markers and line.
First, we load a custom marker image using map.loadImage(). Once the image is loaded, we add it to the map using map.addImage().
Next, we create a GeoJSON source named "points" and assign it the features from our imported GeoJSON data. Each feature represents a point on the map with its coordinates and a title property.
Then, we create a GeoJSON source named "line" and assign it a LineString geometry type with the coordinates from our GeoJSON data.
Finally, we add a symbol layer to display the custom markers on the map, using the custom marker image and the feature's title property. We also add a line layer to visually connect the points on the map.

#Conclusion:
By following this blog post, you have learned how to create interactive maps using React and Mapbox GL JS in a NextJs application. You now have the knowledge and skills required to develop engaging and visually mapping solutions for your web applications. The foundations laid here will enable you to further explore and experiment with React and Mapbox GL JS, unlocking the full potential of interactive maps in your NextJS or any react projects.
With the ability to integrate maps into your applications, you can provide users with an immersive and interactive experience, enabling them to visualize and interact with geographic data in a meaningful way. So go ahead and start building amazing maps that bring your data to life!
Stay tuned for more exciting topics and tutorials in our future blog posts. Happy mapping!

Top comments (1)

Collapse
 
aazad_waf profile image
Aazad Waf

good explanation!