Introduction to Mapbox and React
Published on Feb 3, 2021 by Ben Tyler
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.
REACT_APP_MAPBOX_TOKEN=<YOUR_TOKEN_HERE>
Next, we need to add Mapbox GL JS to our project as a dependency.
# yarnyarn add mapbox-gl# npmnpm install mapbox-gl
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.
// ./app.jsimport React, { useRef, useEffect } from "react"import mapboxgl from "mapbox-gl"// import the mapbox styles// alternatively can use a link tag in the head of public/index.html// see https://docs.mapbox.com/mapbox-gl-js/api/import "mapbox-gl/dist/mapbox-gl.css"// Grab the access token from your Mapbox account// I typically like to store sensitive things like this// in a .env filemapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKENconst App = () => { const mapContainer = useRef() // this is where all of our map logic is going to live // adding the empty dependency array ensures that the map // is only rendered once useEffect(() => { // create the map and configure it // check out the API reference for more options // https://docs.mapbox.com/mapbox-gl-js/api/map/ const map = new mapboxgl.Map({ container: mapContainer.current, style: "mapbox://styles/mapbox/streets-v11", center: [-87.903982, 43.020403], zoom: 12, }) // cleanup function to remove map on unmount return () => map.remove() }, []) return <div ref={mapContainer} style={{ width: "100%", height: "100vh" }} />}export default App
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.
// Grab the access token from your Mapbox account// I typically like to store sensitive things like this// in a .env filemapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKEN
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.
const App = () => { const mapContainer = useRef() // this is where all of our map logic is going to live // adding the empty dependency array ensures that the map // is only created once useEffect(() => { // create the map and configure it // check out the API reference for more options // https://docs.mapbox.com/mapbox-gl-js/api/map/ const map = new mapboxgl.Map({ container: mapContainer.current, style: "mapbox://styles/mapbox/streets-v11", center: [-87.903982, 43.020403], zoom: 12, }) // cleanup function to remove map on unmount return () => map.remove() }, []) return <div ref={mapContainer} style={{ width: "100%", height: "100vh" }} />}export default App
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
If you found thus post useful, give me a follow on Twitter or consider picking up a copy of the Building Interactive Maps with React course.
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/)
About Me
Howdy, I am Ben Tyler. I am a product-focused engineer who cares deeply about finding the simplest solution to a user's problem.
I love collaborating on projects, so if you need a hand, please schedule a call or get in touch at hello@lostcreekdesigns.co!
Schedule a Call!