These docs are a work in progress and may not be fully up to date. Some pages may contain internal notes for our team.
Skip to Content

How to — add a map provider

Adding a fifth map provider touches the widget (tile URL templates + attribution + style builder) and the dashboard (provider picker + API key guide). No backend change is required — the map provider and API key are stored as design.* settings in the finder’s JSON column.

The four existing providers are: TomTom, Mapbox, HERE, and OpenStreetMap.

Step 1 — Add the provider to the widget’s mapSettings.js

The widget builds MapLibre-compatible style objects in dropafinder-app-external/ext/2/source/src/lib/mapSettings.js. This is the file you edit most heavily.

1a — Add the provider to the MapProvider type normalizer

Extend normalizeMapProvider() with the new provider slug:

export function normalizeMapProvider(value) { switch (value) { case 'tomtom': case 'mapbox': case 'here': case 'osm': case 'stadia': // ← new provider return value; default: return 'tomtom'; } }

1b — Add attribution text

The DEFAULT_ATTRIBUTION object holds the attribution string required by each provider’s terms of service. Attribution is passed to MapLibre and rendered in the map corner:

const DEFAULT_ATTRIBUTION = { tomtom: '© TomTom', mapbox: '© Mapbox © OpenStreetMap', here: '© HERE', osm: '© OpenStreetMap contributors', stadia: '© Stadia Maps © OpenMapTiles © OpenStreetMap contributors', // ← add };

Check the new provider’s terms of service for the exact required attribution string.

1c — Add style variant support

If the new provider supports dark/satellite/hybrid styles, add the configuration object (matching the HERE pattern):

const STADIA_STYLE_IDS = { standard: 'stamen_toner_lite', dark: 'alidade_smooth_dark', // satellite and hybrid: null if not supported };

If the provider supports only one style, update isMapStyleVariantSupported() to restrict it:

export function isMapStyleVariantSupported(provider, styleVariant) { if (provider === 'osm' || provider === 'stadia') { return styleVariant === 'standard' || styleVariant === 'dark'; } return true; }

1d — Add the style builder function

Add a buildStadiaStyle() function following the pattern of the existing builders:

function buildStadiaStyle(styleVariant, apiKey) { const styleId = STADIA_STYLE_IDS[styleVariant] ?? STADIA_STYLE_IDS.standard; return buildSingleSourceStyle( [`https://tiles.stadiamaps.com/tiles/${styleId}/{z}/{x}/{y}.png?api_key=${apiKey}`], 256, DEFAULT_ATTRIBUTION.stadia ); }

buildSingleSourceStyle(tiles, tileSize, attribution) returns a MapLibre style object with a single raster source. Use it for any provider that serves raster tiles; TomTom hybrid is the example of a multi-source style.

1e — Register in buildMapStyle()

Add a case to the buildMapStyle() switch:

export function buildMapStyle({ provider, styleVariant, apiKey }) { switch (provider) { case 'mapbox': return buildMapboxStyle(styleVariant, apiKey); case 'here': return buildHereStyle(styleVariant, apiKey); case 'osm': return buildSingleSourceStyle(OSM_TILES, 256, DEFAULT_ATTRIBUTION.osm); case 'stadia': // ← add return buildStadiaStyle(styleVariant, apiKey); // ← add case 'tomtom': default: return buildTomTomStyle(styleVariant, apiKey); } }

1f — Update providerNeedsApiKey()

If the new provider requires an API key:

export function providerNeedsApiKey(provider, tileSet) { if (tileSet === TOMTOM_GIFT_TILE_SET) return false; return provider !== 'osm'; // all others require a key — no change needed for most providers }

OSM is the only key-free provider today. If the new provider is also key-free, add it to the exception:

return provider !== 'osm' && provider !== 'stadia-free';

Step 2 — Add the provider to the dashboard’s mapSettings.ts

The dashboard has a mirrored (TypeScript) version of the provider registry in dropafinder-app-nextjs/src/lib/mapSettings.ts.

2a — Extend the MapProvider type

export type MapProvider = 'tomtom' | 'mapbox' | 'here' | 'osm' | 'stadia';

2b — Add to MAP_PROVIDER_OPTIONS

export const MAP_PROVIDER_OPTIONS: Array<{ value: MapProvider; label: string }> = [ { value: 'tomtom', label: 'TomTom' }, { value: 'mapbox', label: 'Mapbox' }, { value: 'here', label: 'HERE' }, { value: 'osm', label: 'OpenStreetMap' }, { value: 'stadia', label: 'Stadia Maps' }, // ← add ];

2c — Add the API key guide URL

export const MAP_PROVIDER_API_KEY_GUIDES: Record<MapProvider, { label: string; url: string }> = { // ...existing entries... stadia: { label: 'Stadia Maps API key guide', url: 'https://docs.stadiamaps.com/authentication/', }, };

The API key guide link appears in MapsSection.tsx (dropafinder-app-nextjs/src/components/finders/v2/sections/MapsSection.tsx) automatically via getMapProviderApiKeyGuide(), so no changes to the section component are needed unless the new provider requires custom UI.

2d — Update normalizeMapProvider() in mapSettings.ts

export function normalizeMapProvider(value: unknown): MapProvider { switch (value) { case 'tomtom': case 'mapbox': case 'here': case 'osm': case 'stadia': // ← add return value; default: return 'tomtom'; } }

Also update isMapStyleVariantSupported() to match the widget’s version.

Step 3 — Add env var for dashboard Live Preview key (optional)

If you want the dashboard’s Live Preview to render maps for this provider using a shared key (the way TomTom’s gift tile set works), add an env var to dropafinder-app-nextjs/.env.local:

NEXT_PUBLIC_STADIA_KEY=your_key_here

Then update getResolvedMapApiKey() in mapSettings.ts to fall back to it:

case 'stadia': return fallbackKeys?.stadia ?? '';

Step 4 — Verify locally

  1. Build the widget: npm run build:dev in ext/2/source/.
  2. Open the Finder Builder at http://localhost:3000.
  3. Navigate to MapsBase Map. The new provider should appear in the dropdown.
  4. Select it, enter an API key, and confirm the Live Preview renders tiles from the new provider.
  5. Test each supported style variant (standard, dark, etc.) in the Live Preview.

Step 5 — Deploy

Both the widget and the dashboard changed:

# 1. Widget first cd "/Users/codydavis/Local Sites/dropafinder-app-external/ext/2/source" npm run deploy:02 # 2. Dashboard second cd "/Users/codydavis/Local Sites/dropafinder-app-nextjs" git push origin main

See deploy for the full ritual.

Where to next

  • Customer-facing map provider reference: content/customization/map-providers.md
  • Add an autocomplete provider (separate surface): add-autocomplete-provider