External widget — map providers
The widget supports four map tile providers: TomTom, Mapbox, HERE, and OSM (OpenStreetMap). All four are rendered through a single MapLibre GL JS instance using raster tile sources — there is no vector style sheet for any provider. Provider selection, API key resolution, and style construction are centralised in src/lib/mapSettings.js.
Provider enumeration
mapSettings.js:30–40 — normalizeMapProvider accepts a string and returns one of four canonical values:
export function normalizeMapProvider(value) {
switch (value) {
case 'tomtom':
case 'mapbox':
case 'here':
case 'osm':
return value;
default:
return 'tomtom';
}
}tomtom is the default for any unrecognised value, including legacy values such as google and the empty string.
Provider selection from finder config
mapSettings.js:70–102 — resolveMapSettings is the public entry point. It accepts the mapDesign sub-object from the finder payload (found at payload.finder.design.map or assembled from flat payload.finder.settings entries with names like design.map.provider).
App.svelte:60–74 — getMapDesignForValidation shows both read paths:
// App.svelte:61–73
const mapDesign = nextPayload?.finder?.design?.map;
if (mapDesign && typeof mapDesign === 'object') {
return mapDesign; // new enriched payload shape
}
const settings = nextPayload?.finder?.settings ?? [];
return {
provider: getSettingValue(settings, 'design.map.provider'),
tileSet: getSettingValue(settings, 'design.map.tileSet'),
styleVariant: getSettingValue(settings, 'design.map.styleVariant'),
apiKey: getSettingValue(settings, 'design.map.apiKey'),
};When provider is not set on mapDesign, resolveMapSettings falls back to inferring the provider from the legacy tileSet field (mapSettings.js:75–89):
tileSet value | Resolved provider |
|---|---|
mapbox | mapbox |
here | here |
osm | osm |
tomtom, tomtom-finder-beta, google, anything else | tomtom |
resolveMapSettings returns { provider, styleVariant, tileSet, apiKey }.
Style variants
mapSettings.js:42–60 — normalizeMapStyleVariant accepts standard, dark, satellite, hybrid; any other value defaults to standard.
OSM only supports standard — isMapStyleVariantSupported returns false for any other variant when the provider is osm (mapSettings.js:54–56), and normalizeSupportedMapStyleVariant enforces that by falling back to standard.
TomTom
mapSettings.js:157–192 — buildTomTomStyle constructs a MapLibre style object for the TomTom Maps API.
| Style variant | Tile URL pattern |
|---|---|
standard | https://api.tomtom.com/map/1/tile/basic/main/{z}/{x}/{y}.png?key={apiKey} |
dark | https://api.tomtom.com/map/1/tile/basic/night/{z}/{x}/{y}.png?key={apiKey} |
satellite | https://api.tomtom.com/map/1/tile/sat/main/{z}/{x}/{y}.jpg?key={apiKey} |
hybrid | Satellite layer + https://api.tomtom.com/map/1/tile/hybrid/main/{z}/{x}/{y}.png?key={apiKey} overlay |
Hybrid uses two raster sources — satellite and overlay — both at 256px tile size.
Attribution string: © TomTom (mapSettings.js:5).
TomTom gift tile set
mapSettings.js:1 — TOMTOM_GIFT_TILE_SET = 'tomtom-finder-beta'. When tileSet is tomtom-finder-beta, providerNeedsApiKey returns false (mapSettings.js:104–110) and getResolvedMapApiKey returns the build-time VITE_API_TOMTOM_KEY env var as the fallback (mapSettings.js:117–118). This tile set is used for finders on the shared LocationFinders key, so customers do not need to supply their own TomTom key.
Mapbox
mapSettings.js:194–199 — buildMapboxStyle uses Mapbox Styles API raster tiles at 512px tile size (served as @2x).
| Style variant | Mapbox style ID |
|---|---|
standard | streets-v12 |
dark | dark-v11 |
satellite | satellite-v9 |
hybrid | satellite-streets-v12 |
Tile URL pattern: https://api.mapbox.com/styles/v1/mapbox/{styleId}/tiles/256/{z}/{x}/{y}@2x?access_token={apiKey}
Attribution: © Mapbox © OpenStreetMap (mapSettings.js:6).
HERE
mapSettings.js:201–209 — buildHereStyle uses the HERE Maps API v3 raster endpoint.
| Style variant | path | format | style query param |
|---|---|---|---|
standard | base | png8 | lite.day |
dark | base | png8 | lite.night |
satellite | aerial | jpg | satellite.day |
hybrid | aerial | png8 | hybrid.day |
Tile URL pattern: https://maps.hereapi.com/v3/{path}/mc/{z}/{x}/{y}/{format}?style={style}&apiKey={apiKey}
Attribution: © HERE (mapSettings.js:7).
OSM (OpenStreetMap)
mapSettings.js:24–28 — Three tile servers are included in a round-robin array:
const OSM_TILES = [
'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png',
'https://b.tile.openstreetmap.org/{z}/{x}/{y}.png',
'https://c.tile.openstreetmap.org/{z}/{x}/{y}.png',
];buildMapStyle (mapSettings.js:212–224) passes all three to buildSingleSourceStyle as the tiles array. MapLibre distributes tile requests across them automatically.
Attribution: © OpenStreetMap contributors (mapSettings.js:8).
OSM requires no API key — providerNeedsApiKey returns false for osm (mapSettings.js:108–110). getResolvedMapApiKey returns '' for OSM (mapSettings.js:129–130).
⚠️ Warning: The OSM tile servers have usage policy restrictions . Heavy-traffic production finders should use a commercial provider.
API key handling
mapSettings.js:112–131 — getResolvedMapApiKey resolves the API key in priority order:
apiKeyfrom the finder payload (mapDesign.apiKey), if non-empty and at least 5 characters.- Build-time environment variable fallback (
VITE_API_TOMTOM_KEY,VITE_API_MAPBOX_KEY,VITE_API_HERE_KEY) via thefallbackKeysargument. - Empty string (OSM and
tomtom-finder-betatile set).
// mapSettings.js:112–131
export function getResolvedMapApiKey({ provider, tileSet, apiKey, fallbackKeys }) {
if (typeof apiKey === 'string' && apiKey.trim().length >= 5) {
return apiKey; // customer-supplied key from payload
}
if (tileSet === TOMTOM_GIFT_TILE_SET) {
return fallbackKeys.tomtom ?? '';
}
switch (provider) {
case 'mapbox': return fallbackKeys.mapbox ?? '';
case 'here': return fallbackKeys.here ?? '';
case 'tomtom': return fallbackKeys.tomtom ?? '';
case 'osm':
default: return '';
}
}App.svelte:34–36 declares the build-time fallback keys:
const TOMTOM_API_KEY = import.meta.env.VITE_API_TOMTOM_KEY;
const MAPBOX_API_KEY = import.meta.env.VITE_API_MAPBOX_KEY;
const HERE_API_KEY = import.meta.env.VITE_API_HERE_KEY;These are passed as fallbackKeys to getResolvedMapApiKey inside hasValidMapKey (App.svelte:78–93). The customer-supplied key in the finder payload always takes precedence.
Map key validation at boot
App.svelte:76–93 — Before applying any payload (CDN or preview bridge), hasValidMapKey is called. It checks whether the resolved API key is a non-empty string of at least 5 characters, unless the provider is OSM or the tomtom-finder-beta tile set (both of which pass regardless). If validation fails, applyPayload throws 'Finder is missing a valid map API key.' and the widget renders an error card.
Style construction (buildMapStyle)
mapSettings.js:212–224 — The top-level function used by the Map component:
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 'tomtom':
default: return buildTomTomStyle(styleVariant, apiKey);
}
}The return value is a MapLibre GL JS style object (version 8) with sources and layers. All sources are type: 'raster'. There are no symbol layers, no vector sources, and no sprite/glyph configuration — the map is pure raster tile rendering.
Style cache key
mapSettings.js:226–228 — getMapStyleKey returns a string key that encodes the full style identity:
export function getMapStyleKey({ provider, styleVariant, apiKey, tileSet }) {
return `${provider}:${styleVariant}:${tileSet}:${apiKey ?? ''}`;
}The Map component uses this key to avoid recreating the MapLibre instance when an incoming preview payload produces an identical style.
Attribution
Attribution is embedded in each raster source’s attribution field and rendered by MapLibre’s built-in attribution control. No manual attribution rendering is required. The default strings are defined in mapSettings.js:3–9:
const DEFAULT_ATTRIBUTION = {
tomtom: '© TomTom',
mapbox: '© Mapbox © OpenStreetMap',
here: '© HERE',
osm: '© OpenStreetMap contributors',
};Marker rendering
Markers are rendered as HTML elements positioned over the MapLibre canvas — not as map symbols baked into the tile layer. This is handled by the Map component in src/components/Map.svelte using MapLibre’s Marker class. The marker implementation is provider-agnostic; the same HTML marker is used regardless of which raster tile provider is active.
Related pages
- overview.md — widget architecture overview
- cdn-and-pointer.md — how the
apiKeyfield arrives in the finder payload - stores-and-state.md — how
designStoreexposesdesign.mapto the Map component - directory-structure.md — location of map-related source files