Skip to content

Migrate from Mapbox to Stadia Maps

Switching from Mapbox may seem like a daunting task. In this guide, we'll show you how to quickly and easily get up and running with Stadia Maps' styles, APIs, and SDKs.

Get Started With a Free Account

Maps

Once you decide on a Stadia Maps style, all you need to update a couple of lines a code and you're all set for most use cases!

Code Examples

If you need to update a web application, in most cases, all you need to do is update a few lines of code to enable the use of MapLibre GL JS.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Display a map on a webpage</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />

-<link href="https://api.mapbox.com/mapbox-gl-js/v3.7.0/mapbox-gl.css" rel="stylesheet">
+<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css' />
-<script src="https://api.mapbox.com/mapbox-gl-js/v3.7.0/mapbox-gl.js"></script>
+<script src='https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js'></script>

<style>
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>

</head>
<body>
<div id="map"></div>

<script>
-    mapboxgl.accessToken = '<your access token here>';
-    const map = new mapboxgl.Map({
+    var map = new maplibregl.Map({
-        style: 'mapbox://styles/mapbox/streets-v12', // style URL
+        style: 'https://tiles.stadiamaps.com/styles/alidade_smooth.json', // style URL
        container: 'map', // container ID
        center: [-74.5, 40], // starting position [lng, lat]. Note that lat must be set between -90 and 90
        zoom: 9 // starting zoom
    });
</script>

</body>
</html>

Geocoding

Stadia Maps has geocoding and search APIs which work similarly to those you already use. And for the classic autocomplete search box, we have a ready-made control that's practically drop-in!

A replacement for Mapbox's Search Box, our Autocomplete Search allows you to easily build interactive search-as-you-type user experiences to help users get results faster.

Code Examples
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Add Search Box to a Web Map</title>
    <!-- Default styling. Feel free to remove! -->
-   <link href="https://api.mapbox.com/mapbox-assembly/v1.3.0/assembly.min.css" rel="stylesheet">
+   <link href="https://unpkg.com/maplibre-gl@4.0.2/dist/maplibre-gl.css" rel="stylesheet" />
-   <script id="search-js" defer="" src="https://api.mapbox.com/search-js/v1.0.0-beta.22/web.js"></script>
+   <script src="https://unpkg.com/maplibre-gl@4.0.2/dist/maplibre-gl.js"></script>
-   <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet">
+   <link href="https://unpkg.com/@stadiamaps/maplibre-search-box/dist/style.css" rel="stylesheet" />
-   <script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script>
+   <script src="https://unpkg.com/@stadiamaps/maplibre-search-box/dist/maplibre-search-box.umd.js"></script>
</head>
    <body style="margin: 0; padding: 0">
        <div id="map" style="height: 100vh; width: 100vw"></div>
        <script type="application/javascript">
-           ACCESS_TOKEN = 'YOUR-MAPBOX-KEY';
+           //You can use Stadia Maps domain authentication

-           const searchJS = document.getElementById('search-js');
-           searchJS.onload = function () {
-               const searchBox = new MapboxSearchBox();
-               searchBox.accessToken = ACCESS_TOKEN;
-               searchBox.options = {
-                   types: 'address,poi',
-                   proximity: [-73.99209, 40.68933]
-               };
-               searchBox.marker = true;
-               searchBox.mapboxgl = mapboxgl;
-               map.addControl(searchBox);
-           };
+           var control = new maplibreSearchBox.MapLibreSearchControl({
+               useMapFocusPoint: true,
+               onResultSelected: feature => {
+               // You can add code here to take some action when a result is selected.
+               console.log(feature.geometry.coordinates);
+           },
+               // You can also use our EU endpoint to keep traffic within the EU using the basePath option:
+               // baseUrl: "https://api-eu.stadiamaps.com",
+           });
+
+           var map = new maplibregl.Map({
+               container: "map",
+               // You can also use our EU endpoints here by changing the host to tiles-eu.stadiamaps.com
+               style: "https://tiles.stadiamaps.com/styles/alidade_smooth.json", // stylesheet location
+               center: [-74.5, 40], // starting position [lng, lat]
+               zoom: 2, // starting zoom
+           });
+           map.addControl(control, "top-left");
        </script>
    </body>
</html>
Building a Mobile Search Experience?

We also have autocomplete search SDKs available for SwiftUI and Jetpack Compose!

Forward geocoding

With forward geocoding, you can search for places by name or address and get their location, website, postal code, and more.

Code Examples
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Vector Map Demo</title>
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
-       <script type="text/javascript" src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script>
+       <script type="text/javascript" src="//unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
-       <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet">
+       <link href="//unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css" rel="stylesheet" />
        <style type="text/css">
            body { margin: 0; padding: 0; }
            #map { position: absolute; top: 0; bottom: 0; width: 100%; }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <script type="text/javascript">

-         mapboxgl.accessToken = '<YOUR-MAPBOX-ACCESS-TOKEN>';
+         api_key = '<YOUR-STADIA-MAPS-API-KEY>' // If this is a public web app, please use domain authentication.

-         var map = new mapboxgl.Map({
+         var map = new maplibregl.Map({
        container: 'map',
-          style: 'mapbox://styles/mapbox/streets-v11',
+          style: 'https://tiles.stadiamaps.com/styles/alidade_smooth.json',  // Style URL; see our documentation for more options
        center: [12, 53],  // Initial focus coordinate
        zoom: 4
        });

        // MapLibre GL JS does not handle RTL text by default,
        // so we recommend adding this dependency to fully support RTL rendering if your style includes RTL text
+         maplibregl.setRTLTextPlugin('https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js');

        // Add zoom and rotation controls to the map.
+         map.addControl(new maplibregl.NavigationControl());

        // Function to perform forward geocoding
        function geocode(address) {
-            const geocodingUrl = `https://api.mapbox.com/search/geocode/v6/forward?q=${encodeURIComponent(address)}&access_token=${mapboxgl.accessToken}`;
+            const geocodingUrl = `https://api.stadiamaps.com/geocoding/v1/search?text=${encodeURIComponent(address)}&api_key=${api_key}`;

            fetch(geocodingUrl)
                .then(response => response.json())
                .then(data => {
-                    const [lng, lat] = data.features[0].center;
+                    const [lng, lat] = data.features[0].geometry.coordinates;
                    console.log(`Coordinates: ${lng}, ${lat}`);

                    // Fly to the location and add a marker
                    map.flyTo({ center: [lng, lat], zoom: 14 });
-                    new mapboxgl.Marker()
+                    new maplibregl.Marker()
                        .setLngLat([lng, lat])
                        .addTo(map);
                })
                .catch(error => console.error('Error fetching geocoding data:', error));
        }

        geocode("1600 Pennsylvania Ave NW, Washington, DC");

        </script>
    </body>
</html>

Installation Instructions

The Stadia Maps Python SDK is available through any package manager that supports PyPi.

PyPI - Downloads

pip install stadiamaps
poetry add stadiamaps
- from mapbox import Geocoder
+ import os
+ import stadiamaps
+ from stadiamaps.rest import ApiException

# You can also use our EU endpoint to keep traffic within the EU like so:
# configuration = stadiamaps.Configuration(host="https://api-eu.stadiamaps.com")
+ configuration = stadiamaps.Configuration()

# Replace with your actual API key
- access_token = "<YOUR-MAPBOX-ACCESS-TOKEN>"
+ configuration.api_key['ApiKeyAuth'] = "<YOUR-STADIA-MAPS-API-KEY>"

- geocoder = Geocoder(access_token=access_token)

+ with stadiamaps.ApiClient(configuration) as api_client:
+    # Create an instance of the API class
+    api_instance = stadiamaps.GeocodingApi(api_client)

address = '1600 Pennsylvania Ave NW, Washington, DC 20500'

+ try:
-   res = geocoder.forward(address)
+   res = api_instance.search(text=address)
-   geo_data = res.json()
-   coordinates = geo_data['features'][0]['geometry']['coordinates']
+   coordinates = res.to_dict()['features'][0]['geometry']['coordinates']
    print(f"Coordinates for {address}: {coordinates}")
- except:
+ except ApiException as e:
    # Add your error handling here
-   print("Error when calling the API: {res.status_code}")
+   print("Exception when calling the Stadia Maps API: %s\n" % e)

Reverse geocoding

With reverse geocoding, you can find nearby addresses, the city, state, and more.

Code Examples
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Vector Map Demo</title>
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
-       <script type="text/javascript" src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script>
+       <script type="text/javascript" src="//unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
-       <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet">
+       <link href="//unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css" rel="stylesheet" />
        <style type="text/css">
            body { margin: 0; padding: 0; }
            #map { position: absolute; top: 0; bottom: 0; width: 100%; }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <script type="text/javascript">

-         mapboxgl.accessToken = '<YOUR-MAPBOX-ACCESS-TOKEN>';
+         api_key = '<YOUR-STADIA-MAPS-API-KEY>' // If this is a public web app, please use domain authentication.

-         var map = new mapboxgl.Map({
+         var map = new maplibregl.Map({
        container: 'map',
-          style: 'mapbox://styles/mapbox/streets-v11',
+          style: 'https://tiles.stadiamaps.com/styles/alidade_smooth.json',  // Style URL; see our documentation for more options
        center: [12, 53],  // Initial focus coordinate
        zoom: 4
        });

        // MapLibre GL JS does not handle RTL text by default,
        // so we recommend adding this dependency to fully support RTL rendering if your style includes RTL text
+         maplibregl.setRTLTextPlugin('https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js');

        // Add zoom and rotation controls to the map.
+         map.addControl(new maplibregl.NavigationControl());

        // Function to perform forward geocoding
        function geocode(lng, lat) {
-            const geocodingUrl = https://api.mapbox.com/search/geocode/v6/reverse?longitude=${lng}&latitude=${lat}&access_token=${mapboxgl.accessToken}`;
+            const geocodingUrl = `https://api.stadiamaps.com/geocoding/v1/reverse?point.lon=${encodeURIComponent(lng)}&point.lat=${encodeURIComponent(lat)}&api_key=${api_key}`;

            fetch(geocodingUrl)
                .then(response => response.json())
                .then(data => {
-                    const label = data.features[0].properties.name;
+                    const label = data.features[0].properties.label;

                    console.log(`Label: ${label}`);

                    // Fly to the location, add a popup, and a marker.
                    map.flyTo({ center: [lng, lat], zoom: 14 });

-                    var popup = new mapboxgl.Popup({
+                    var popup = new maplibregl.Popup({
                        anchor: 'bottom',
                        offset: [0, -64] // height - shadow
                    })
                    .setText(`${label}`);

-                    new mapboxgl.Marker()
+                    new maplibregl.Marker()
                        .setLngLat([lng, lat])
                        .setPopup(popup)
                        .addTo(map);
                })
                .catch(error => console.error('Error fetching geocoding data:', error));
        }

        geocode(24.750645, 59.444351);

        </script>
    </body>
</html>

Installation Instructions

The Stadia Maps Python SDK is available through any package manager that supports PyPi.

PyPI - Downloads

pip install stadiamaps
poetry add stadiamaps
- from mapbox import Geocoder
+ import os
+ import stadiamaps
+ from stadiamaps.rest import ApiException

# You can also use our EU endpoint to keep traffic within the EU like so:
# configuration = stadiamaps.Configuration(host="https://api-eu.stadiamaps.com")
+ configuration = stadiamaps.Configuration()

# Replace with your actual API key
- access_token = "<YOUR-MAPBOX-ACCESS-TOKEN>""
+ configuration.api_key['ApiKeyAuth'] = "<YOUR-STADIA-MAPS-API-KEY>"

- geocoder = Geocoder(access_token=access_token)

+ with stadiamaps.ApiClient(configuration) as api_client:
+    # Create an instance of the API class
+    api_instance = stadiamaps.GeocodingApi(api_client)

coords = (59.444351, 24.750645)

try:
-    res = geocoder.reverse(lon=coords[1], lat=coords[0])
+    res = api_instance.reverse(*coords)
-    geo_data = res.json()
-    label = geo_data['features'][0]['place_name']
+    label = res.to_dict()['features'][0]['properties']['label']
    print(f"Label for {coords}: {label}")
- except:
+ except ApiException as e:
    # Add your error handling here
-   print("Error when calling the API: {res.status_code}")
+   print("Exception when calling the API: %s\n" % e)

Didn't find what you need?

We can't cover everything in one guide, but our expert team is standing by ready to help! Talk to our real human support today directly via email, chat, or social media