I like to write almost as much as I like to build. I write about dashboards, maps, freelancing, music, and the outdoors. If this interests you too, please join my mailing list to get updates whenever I publish new content.
Subscribe
Introduction to Mapbox and React
Date: 2/3/2021
Time to Read: 4 minutes
This post is part of a series of Mapbox tutorials. The majority of the guides will focus on how to use Mapbox with React, but will also additionally focus on other parts of the Mapbox suite such as Mapbox Studio and various Mapbox APIs. The series will start with relatively simple use cases and build into more complex examples.
What You Will Learn
This post is intended to serve as a guide on how to get up and running with Mapbox GL JS and React. It will walk you through how to create a basic React map component and how to add some common customizations to the map. By the end of this guide you will be able to create a basic fullscreen interactive map using Mapbox GL JS and React.
Prerequisites
- basic familiarity with React
Introduction to Mapbox
If you are already familiar with Mapbox, go ahead and skip ahead to Application Setup. In short, Mapbox is a powerful platform that provides the building blocks for building map and location-driven applications for the web, mobile, and AR. A lot of the mapping experiences you come across in the wild are likely powered in some capacity by Mapbox (i.e. Strava, New York Times, Shopify, Square). Their main product offerings are:
- Maps: Brilliant map styles and SDKs for interacting with them
- Navigation: Powerful routing engine for developing navigation experiences
- Search: Geocoding service
- Studio: Powerful UI for developing custom maps and visualizations
- Vision: Suite of tools centered around leveraging cameras and AI
- Data: Robust datasets including boundaries, traffic, and movement data
This series will focus on their Maps and Studio products. Hoping I get a chance to dig into some of their other offerings like Navigation, Vision, and Search down the road though.
This guide in particular is going to focus on how to get started using Mapbox GL JS with React. This JavaScript library will allow us to add beautiful and highly interactive maps to any React application with a minimal amount of code.
Application Setup
For ease of use, we are going to use create-react-app to get our application up and running. If you would like to follow along, you can find this guide in my sandbox repo.
Mapbox requires that you have an account to use Mapbox GL JS. If you do not have an account, head on over to their signup page. After creating your account, login and navigate to your account page at https://account.mapbox.com/. You should see a section titled "Access Tokens" as well as a "Default public token". In the root of the project, create a new .env
file and copy your access token that you just tracked down. You will want to add this token to the .env
file. It is generally best practice to store sensitive information like access tokens in a .env
file and keep them out of version control.
1REACT_APP_MAPBOX_TOKEN=<YOUR_TOKEN_HERE>2
Next, we need to add Mapbox GL JS to our project as a dependency.
1# yarn2yarn add mapbox-gl3
4# npm5npm install mapbox-gl6
Creating the Map
With the basic application infrastructure setup and dependencies installed, we can create our fullscreen interactive map. If you are just looking to grab a snippet and go on your way, the below code block is your ticket. Otherwise, I will be walking through they key concepts block by block below.
1// ./app.js2import React, { useRef, useEffect } from "react"3import mapboxgl from "mapbox-gl"4// import the mapbox styles5// alternatively can use a link tag in the head of public/index.html6// see https://docs.mapbox.com/mapbox-gl-js/api/7import "mapbox-gl/dist/mapbox-gl.css"8
9// Grab the access token from your Mapbox account10// I typically like to store sensitive things like this11// in a .env file12mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKEN13
14const App = () => {15 const mapContainer = useRef()16
17 // this is where all of our map logic is going to live18 // adding the empty dependency array ensures that the map19 // is only rendered once20 useEffect(() => {21 // create the map and configure it22 // check out the API reference for more options23 // https://docs.mapbox.com/mapbox-gl-js/api/map/24 const map = new mapboxgl.Map({25 container: mapContainer.current,26 style: "mapbox://styles/mapbox/streets-v11",27 center: [-87.903982, 43.020403],28 zoom: 12,29 })30
31 // cleanup function to remove map on unmount32 return () => map.remove()33 }, [])34
35 return <div ref={mapContainer} style={{ width: "100%", height: "100vh" }} />36}37
38export default App39
Alright, let's step through the above snippet line by line starting with the access token bit. Mapbox requires you to have an access token to use their Mapbox GL JS library. We already grabbed an access token in the application setup step and stored it in a .env
file. We can now reference that variable in our application.
1// Grab the access token from your Mapbox account2// I typically like to store sensitive things like this3// in a .env file4mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKEN5
We start by creating a reference for the map container using the [useRef](https://reactjs.org/docs/hooks-reference.html#useref)
hook. We will use this ref to tell Mapbox where to render the map. Where the meat and potatoes of our map logic lives though is inside of the [useEffect](https://reactjs.org/docs/hooks-reference.html#useeffect)
hook. Placing the logic within the useEffect
hook ensures that the map does not render until the component has mounted and passing an empty dependency array to the hook ensures that the map is only rendered once.
The actual logic required to initialize the map is minuscule. Six lines of code to create a beautiful and interactive map! All we need to do is create a new variable called map
and set its value to a new instance of a Mapbox GL JS map. The constructor can take a whole slew of configuration options (many of these will be covered in later posts), but we will be keeping it simple for this example. The only required options are container
and style
. You can find great descriptions of these two options + all the other available options in the Mapbox Docs. I added in the optional center
and zoom
options to render a nice map of Milwaukee.
We will want to add a cleanup function to the useEffect
hook to ensure that our map is removed when the component unmounts. Lastly, we pass our ref to the div
that is returned from our component and assign styles to ensure that the map takes up the full viewport width and height. That is it! If you start the application you should now have a fully interactive full screen map of Milwaukee that you can zoom and pan around.
1const App = () => {2 const mapContainer = useRef()3
4 // this is where all of our map logic is going to live5 // adding the empty dependency array ensures that the map6 // is only created once7 useEffect(() => {8 // create the map and configure it9 // check out the API reference for more options10 // https://docs.mapbox.com/mapbox-gl-js/api/map/11 const map = new mapboxgl.Map({12 container: mapContainer.current,13 style: "mapbox://styles/mapbox/streets-v11",14 center: [-87.903982, 43.020403],15 zoom: 12,16 })17
18 // cleanup function to remove map on unmount19 return () => map.remove()20 }, [])21
22 return <div ref={mapContainer} style={{ width: "100%", height: "100vh" }} />23}24
25export default App26
Next Steps
There are a whole slew of things we could do to improve the map that are beyond the scope of this first tutorial. The next post in this series will explore the myriad of predefined Mapbox Styles (aka basemaps) that are can be easily added to any map. The tutorial will provide useful context on each style and walk you through common use cases for each.
If you cannot wait until then, here is a list of some other predefined Mapbox Styles you could try out. Just swap out the existing style
option for one of the following style urls.
mapbox://styles/mapbox/streets-v11
mapbox://styles/mapbox/outdoors-v11
mapbox://styles/mapbox/light-v10
mapbox://styles/mapbox/dark-v10
mapbox://styles/mapbox/satellite-v9
mapbox://styles/mapbox/satellite-streets-v11
mapbox://styles/mapbox/navigation-preview-day-v4
mapbox://styles/mapbox/navigation-preview-night-v4
mapbox://styles/mapbox/navigation-guidance-day-v4
mapbox://styles/mapbox/navigation-guidance-night-v4
Useful Links & Resources
- Mapbox Home Page (https://www.mapbox.com/)
- Mapbox Products: Maps (https://www.mapbox.com/maps/)
- Mapbox GL JS Docs (https://docs.mapbox.com/mapbox-gl-js/api/)
- Create React App (https://create-react-app.dev/)