Introduction
In this tutorial, you will learn how to return to your last location mapbox using local storage.
Prerequisites
To start building, you’ll need a basic understanding of web development, Node (v16), yarn, Javascript and React.
Getting Started
Bootstrap a react app using vite with the following command
npm create vite@latest
Give your project a name and Select react
framework and typescript
.
Set up Mapbox
Install mapbox-gl using the following command
npm install mapbox-gl --save
Initialize the Map
Create a new file called Mapbox.tsx
in the src
folder and add the following code
import React, { useEffect, useRef, useState } from 'react';
import mapboxgl from 'mapbox-gl';
const Mapbox: React.FC = () => {
const [map, setMap] = useState<mapboxgl.Map | null>(null);
const [selectedLayer, setSelectedLayer] = useState<string>(
'satellite-streets-v12'
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const mapContainer = useRef<any>(null);
useEffect(() => {
if (map) return;
const mapboxMap = new mapboxgl.Map({
accessToken: import.meta.env.VITE_MAPBOX_TOKEN,
container: mapContainer.current,
style: `mapbox://styles/mapbox/${selectedLayer}`,
center: [0, 0],
zoom: 1,
});
setMap(mapboxMap);
}, [map]);
return (
<>
<div
className='h-screen w-full relative flex flex-col'
ref={mapContainer}
></div>
</>
);
};
export default Mapbox;
-
Import the necessary react hooks and mapbox-gl.
-
Create a state variable to hold the map instance.
-
Create a ref to hold the map container. The map's container is stored in a ref, which allows direct access to the DOM node.
-
Initialize the map instance in the
useEffect
hook. Inside this hook, a new Mapbox map is created and stored in state. The map's container is set to the current value of 'mapContainer', and the map's style, center, and zoom level are also set. The map is initialized using the satelitte-streets-v12 style. -
Return the map container in the render method.
Using local storage to persist users last location on mapbox
Update the map initialization code to the following
// ...Existing code
useEffect(() => {
if (map) return;
const savedCenter = localStorage.getItem('mapCenter');
const savedZoom = localStorage.getItem('mapZoom');
const savedCenterArray = savedCenter ? JSON.parse(savedCenter) : [0, 0];
const savedZoomValue = savedZoom ? parseFloat(savedZoom) : 2;
const mapboxMap = new mapboxgl.Map({
accessToken: import.meta.env.VITE_MAPBOX_TOKEN,
container: mapContainer.current,
style: `mapbox://styles/mapbox/${selectedLayer}`,
center: savedCenterArray,
zoom: savedZoomValue,
});
mapboxMap.on('moveend', () => {
const { lng, lat } = mapboxMap.getCenter();
const zoom = mapboxMap.getZoom();
localStorage.setItem('mapCenter', JSON.stringify([lng, lat]));
localStorage.setItem('mapZoom', zoom.toString());
});
setMap(mapboxMap);
}, [map, selectedLayer]);
// ...Existing code
-
Add an event listener to the map's
moveend
event. This event is fired when the map's center or zoom value changes. When this event is fired, the map's center and zoom values are saved to local storage. -
Get the saved center and zoom values from local storage. If the saved center and zoom values exist, use them to initialize the map.
Final Output
Congratulations! You've persisted a GeoJSON feature layer across different map styles on mapbox using react.
- Mapbox - documentation
- Github repo - Source code
- Live Link - Demo