Skip to main content
Onboarding flows can contain a Map element — a route through several stops, or a single place with its details. Before it can draw anything, the app needs a map provider and a key. All of it is configured once per app, not per flow and not per map: Settings → Apps → your app → Maps

Choose a provider

The provider applies to every Map element in every flow for this app. It sits next to the keys because it selects between them: picking a provider you have no key for is the one mistake that produces a placeholder on every device with nothing to explain it, so the settings page warns you inline when the two disagree.
Both keys are yours. Maps are fetched directly by the device and by the flow editor’s preview, so usage bills to your own Mapbox or Google account. There is deliberately no shared AppDNA key: Mapbox’s Product Terms forbid us serving their imagery on another account’s behalf, and Google bills map requests to whoever owns the key.

Mapbox public token

Create one under Account → Tokens at mapbox.com, then paste it into the Mapbox field. It must be a public token — it starts with pk.. It travels inside every map image URL, so it is public by design; restrict it by URL in the Mapbox dashboard rather than trying to keep it secret. A secret sk. token is rejected by the image API and must never be shipped to devices.

Google Maps API key

In the Google Cloud console, create an API key and enable the APIs you need: Paste the key (it starts with AIza) into the Google Maps field.
The API restrictions dropdown only lists APIs that are already enabled in the project. If it looks empty, enable the ones above in the Library first, then come back to the key — the list refreshes. Key changes can take a few minutes to take effect, so an immediate 403 is not necessarily a mistake.
Restrict it by API, not by application. A Google key accepts only one application restriction — None, HTTP referrers, IP addresses, Android apps, or iOS apps — and the SDK fetches the static map as a plain HTTPS request straight from the device. That request carries no referrer and no bundle ID, so an HTTP-referrer restriction works in the console preview and fails on every device, while an iOS/Android app restriction covers pan & zoom but not the static image.Set Application restrictions: None, then use API restrictions → Restrict key and select only the APIs in the table above. Add a cap under APIs & Services → Quotas so a leaked key cannot run up a bill. That is the combination that works on device and in the console.

Google Places key — a different key

The Google Places API key on the same page is not the same credential and is entirely optional. It is reserved for place search on Google maps, which is not available yet (see Searching for stops and places). It is used only by the console, never shipped to devices, and stored encrypted — so it is never displayed again after you save it.

Searching for stops and places

Search follows the map’s engine, because each provider allows its results to be used only on its own maps: a map drawn with Mapbox searches with Mapbox, and a search never falls back to the other provider. A map drawn with Google has no search yet.
  • Mapbox maps search Mapbox’s permanent geocoding with your app’s own Mapbox token. Permanent results are the only ones Mapbox allows you to store, and they need a card on file on your Mapbox account. Without one, search says so and you can enter coordinates instead.
  • Google maps have no search yet. Enter the coordinates by hand.
A search result’s location is read-only. It shows as “Location from Mapbox” (or “Location from Google Maps”) rather than as numbers. To change it, search again or remove it (a place has Remove place). To place your own pin, use Add stop manually: a stop you add by hand shows its latitude and longitude, and you can move it. Typing coordinates into a stop or place whose location was cleared starts a new, hand-placed one with the same title.

Switching the map engine

Changing Map provider in Settings → Apps → Maps clears the stops that came from the other provider. Before you save, when the change would clear anything, the page says how many stops and places will be cleared. If your app ever had a Mapbox token, stops added before stops recorded their source may have been typed by hand, but cannot be told apart, so they are cleared too and the warning says so. Stops you added by hand are kept. A cleared stop keeps its title, including a title that came from Mapbox. A map placed directly on a step, or directly in an option’s sheet, that is left with nothing to draw is hidden on devices until you search again or enter coordinates. Its Visibility reads “Hidden until this map has a place — search again”, with any condition you had set shown as the one that comes back. The flow editor lists each such map with Open step and Dismiss (which hides the notice only), and the flows list marks the flow Map stops to re-search. The cleared stops are removed from the published flow as well: you do not need to republish. A map inside a row or a stack (including a row or a stack inside an option’s sheet) is hidden the same way only from the next SDK release. App versions built on the current SDK still show it, at the map’s default location, until you search again or enter coordinates, and the flow editor’s notice says so for that map.

”Pinned to Google” / “Pinned to Mapbox”

A map published before the engine became an app setting may name its own provider. It shows Pinned to Google or Pinned to Mapbox, read-only, with Follow the app. Following the app saves the flow, then warns first, in the same way as a switch, if the map’s provider would change or a stop would be cleared. It is applied at once and cannot be undone with Undo.

Pan & zoom

Turning on Interactive (pan & zoom) for a Map element gives the user a real, draggable map instead of a still image. A Map element whose setting was never saved is interactive — the switch shows it on unless you switch it off — while a Map element you add now starts with the switch off. It needs the Google provider, and on Android it also needs one line in your app’s manifest, because the Maps SDK for Android reads its key at build time:
iOS needs nothing for the static map — its Maps SDK takes the key at runtime, so the key you set here is enough. For pan & zoom, an iOS app that integrates via Swift Package Manager needs GoogleMaps.bundle copied to its app bundle root; SwiftPM nests it where the Maps SDK cannot find it, and adding the GoogleMaps package to the app target does not change that. CocoaPods hosts — including React Native and Flutter — are unaffected. See the iOS installation guide. See the Android and iOS installation guides for the full detail, including the CocoaPods linkage settings React Native and Flutter hosts need. Without that manifest line an Android app falls back to the still image — the map simply does not pan. Nothing breaks.

Route line and camera on the pan & zoom map

The pan & zoom map draws the same route as the still image:
  • Route line. When the element has a Fixed route line (an encoded polyline, set in the editor or supplied by your app), the map draws that polyline. Otherwise, with two or more stops, it draws straight segments between the stops. The route colour and width apply to whichever line is drawn. Stops are always shown as markers; polyline points never become markers.
  • Polylines use Google’s encoding at precision 5. Precision-6 polylines (polyline6, as produced by some routing services) are not supported — read as precision 5, every coordinate comes out ten times too large. If any point then falls outside ±90° latitude / ±180° longitude the line is ignored and the map falls back to the stops — that is almost every route. A route whose every point lies within 9° of the equator and 18° of the prime meridian decodes in range instead, and draws in the wrong place. The still image does not check the polyline: it passes it to Mapbox or Google unchanged, and both read it at precision 5 too. Always encode at precision 5.
  • Camera. With Auto-fit to the route and stops on (the default), the map frames the route line and every stop, with a small margin, as soon as the map has a size — and again whenever the route or stops change (for example when your app’s route data arrives after the first frame). If only one point exists, the map centres on it at zoom 15. With Auto-fit off, the map centres on the authored centre at the authored zoom (the same rule as the still image). The user’s own pan and zoom are never overridden except by such a route change.
  • Antimeridian: on iOS, routes that cross the ±180° meridian are not framed correctly; the fit uses a simple min/max bounding box. Android frames with the Google Maps SDK’s bounds builder instead.

When a map shows “Map unavailable”

That placeholder is the deliberate, labelled fallback: a map with no key degrades to a caption, never to a blank box. It appears when: The flow editor’s preview uses the same keys and the same provider as the device, so whatever you see on the canvas is what your users will see.