Let's dive into how to add custom map styles to a React Native app using @rnmapbox/maps.
Obtaining an access token
The default token will allow us to load a map in our app but it does not allow us to add new map styles. So we're going to need to create a new access token with the styles:write permission. It is also recommended to add the styles:read permissions too since we'll eventually need to load that style. Access token permissions can be updated after the fact so it's good practice to only add the permissions you need when you need them.
Setting up a Map View in our application
import MapboxGL from "@rnmapbox/maps"
const MAPBOX_API_KEY = "your-api-key"
MapboxGL.setAccessToken(MAPBOX_API_KEY)In our code, our component will look like this:
<MapboxGL.MapView style={{width: “100%”, height: “100%” }} styleURL=”mapbox://styles/mapbox/streets-v12”/>Our app will look like this:
It's worth noting that styles passed to the map view should be based on the context of how the elements are arranged in our screen component. In addition, the styleURL prop is optional and if we don't pass it then the default Mapbox street style will be used. That said, this is all we need to load a map style.
Uploading a new Map Style - Validation
There are two ways we can allow users to add a MapStyle in our app:
- Allow users to submit style URLs and save them in our database. One constraint of this approach is that we cannot load private map styles in our app unless they were created with our access token (which proves ownership)
- Allow users to upload a JSON file that fits the Mapbox style specification, send that JSON via the Styles API to Mapbox, receive a new style URL in the response and save the URL to our database
Regardless which approach you pick, we'll need some validation. Here's how we would validate a style URL using some regex.
export const validateMapboxStyleUrl = ({ url }) => {
const mapboxStyleUrlValidator = /^mapbox:\/\/styles\/+[A-Za-z_-]+\//g;
return mapboxStyleUrlValidator.test(url);
};import * as yup from "yup";
export const mapboxJsonValidator = yup.object().shape({
version: yup.number().required(),
name: yup.string().required(),
metadata: yup
.object()
.shape({
"mapbox:origin": yup.string().optional(),
"mapbox:autocomposite": yup.boolean().optional(),
"mapbox:type": yup.string().optional(),
"mapbox:sdk-support": yup
.object()
.shape({
js: yup.string().optional(),
android: yup.string().optional(),
ios: yup.string().optional(),
}),
})
.optional(),
center: yup.array().of(yup.number()).required(),
zoom: yup.number().required(),
bearing: yup.number().required(),
pitch: yup.number().required(),
sources: yup
.object()
.shape({
composite: yup
.object()
.shape({ url: yup.string().required(), type: yup.string().required() }),
}),
sprite: yup.string().optional(),
glyphs: yup.string().optional(),
layers: yup.array().of(yup.object()).required(),
created: yup.string().optional(),
id: yup.string().required(),
modified: yup.string().optional(),
owner: yup.string().required(),
visibility: yup.string().required(),
draft: yup.boolean().required(),
});Then use our validator this way
const validatorSuccess = mapboxJsonValidator
.validate(mapboxJsonMapStyle)
.then(() => true)
.catch(() => false);Uploading a new Map Style - Using the Styles API
If we're taking a URL after validating it, we can immediately send it to our database. However, if we're taking a JSON file, after validating on the client, we still need to send the style data to Mapbox to get a style URL that we can actually load.
We'll upload our style to the URL below via a REST POST request with our JSON object passed as data in our request. We also need to specify the content type header as content-type: application/json
URL: https://api.mapbox.com/styles/v1/your-mapbox-user-name?access\_token=<YOUR\_MAPBOX\_ACCESS\_TOKEN?
Once the request is successful we'll get a style URL in the response that we can save in our database.
Loading styles
Now all that's needed to load styles in our app is to retrieve them from the database via any HTTP client like Node's fetch API, Axios or another library that allows us to pass them to our map view via any kind of state mechanism.
Demo
Here's an example of how the map looks like after we load a custom style
Written by

Karel Adotey Mensah
Software Engineer
Karel is a software engineer with a focus on building scalable and reliable web and mobile applications. He has a passion for creating high-quality software solutions that are user-friendly and easy to maintain. Karel is also an advocate for clean code and best practices in software development.
View profile →
