Creating Interactive Maps with React and Mapbox GL JS in a NextJs App
Tags: map, nextjs
Published: 2023-06-08 04:23:06

**#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":

```javascript
npx create-next-app nextjs-mapbox
```


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

```javascript
cd nextjs-mapbox
npm install mapbox-gl react
```


_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:

```javascript
REACT_APP_MAPBOX_ACCESS_TOKEN=your-access-token
```

**#Integrating Mapbox GL JS with React in Next.js:**
Create a new file called `Map.js `in the components folder with the following code:
```javascript
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;

```

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:
```javascript
// 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
        }
      });
    }
  );
});

```
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!