Map view
Show an interactive map alongside your tour stops
AudioGuideKit can show an interactive map tab on the tour screen. Visitors switch between the stop list and the map with a single tap — stops appear as numbered markers, and a route line can guide them between each one.
The map is completely optional. Without a single setting change everything works exactly as before.
Enabling the map
Add mapView: true to your metadata.json:
{
"mapView": true,
"mapProvider": "openstreetmap"
}The tour will open in map view by default. Without this setting the map tab stays hidden.
View modes
A tour screen has two views — map and list — controlled by two independent flags:
| Field | Type | Default | Description |
|---|---|---|---|
mapView | boolean | false | Enable the map view |
listView | boolean | true | Enable the list view |
The header shows a map/list toggle only when both are enabled. With a single view enabled there's no toggle — the tour opens directly into that view.
mapView | listView | Result |
|---|---|---|
true | true (or omitted) | Both — toggle shown, opens on the map |
true | false | Map only — no toggle |
false (or omitted) | true (or omitted) | List only — no toggle (the default) |
false | false | Falls back to the list |
Because listView defaults to true, existing tours are unaffected: omit it to keep the list, set mapView: true to add the map alongside it, or set listView: false (with mapView: true) for a map-only tour.
On a map-only tour (listView: false) the offline placeholder's View list button is hidden automatically — there's no list to fall back to.
Adding coordinates to stops
Only audio stops appear on the map. Add a location field to each stop you want to pin:
{
"id": "1",
"type": "audio",
"title": "Plaça Catalunya",
"location": { "lat": 41.3851, "lng": 2.1734 }
}Stops without a location are silently skipped — no marker is rendered, no errors.
All map fields (mapView, mapProvider, location, mapMarkerIcon, etc.) are listed with descriptions in the Creating your tour reference — alongside every other metadata.json and stop field.
Tile providers
AudioGuideKit supports five map tile providers. OpenStreetMap and CARTO work out of the box with no account or API key. The others need a key set as an environment variable.
| Provider | Key needed? | mapProvider value |
|---|---|---|
| OpenStreetMap | No | "openstreetmap" |
| CARTO | No | "carto" |
| Mapbox | Yes | "mapbox" |
| Jawg Maps | Yes | "jawg" |
| MapTiler | Yes | "maptiler" |
OpenStreetMap (default)
No setup needed. Free for typical usage.
{
"mapProvider": "openstreetmap"
}CARTO
No API key required. Four clean styles to choose from:
| Style | mapStyleId |
|---|---|
| Voyager (default) | rastertiles/voyager |
| Positron (light) | light_all |
| Dark Matter | dark_all |
| Positron no labels | light_nolabels |
| Dark Matter no labels | dark_nolabels |
{
"mapProvider": "carto",
"mapStyleId": "dark_all"
}Mapbox, Jawg, and MapTiler
Copy .env to .env.local and add your key:
VITE_MAPBOX_API_KEY=pk.eyJ1...
VITE_JAWG_API_KEY=your-jawg-token
VITE_MAPTILER_API_KEY=your-maptiler-keyNever put API keys in metadata.json. Use .env.local — it's gitignored and kept off your public repo.
Then set the provider:
{
"mapProvider": "maptiler",
"mapStyleId": "topo-v2"
}Each provider has a default style that works great out of the box. Use mapStyleId to pick a different one.
Mapbox default: mapbox/outdoors-v12. Custom Mapbox Studio styles use "yourname/cl9abc1234def" format.
Jawg built-in styles: jawg-streets, jawg-terrain, jawg-sunny, jawg-lagoon, jawg-dark, jawg-light. Default: jawg-terrain.
MapTiler default: outdoor-v2. Any MapTiler map ID works.
Customizing the map view
Starting position
By default the map fits all stops into view automatically. Use mapCenter and mapZoom to set a fixed starting position instead:
{
"mapCenter": { "lat": 41.3851, "lng": 2.1734 },
"mapZoom": 13
}| Combination | Behaviour |
|---|---|
| Neither set | Fits all stops in view |
mapCenter only | Centers there at zoom 13 |
mapCenter + mapZoom | Centers there at the given zoom |
mapZoom only | Fits all stops, then overrides the zoom level |
Marker styles
By default each audio stop is a small circle showing its stop number, switching to a checkmark once completed. The mapMarker field sets the default style for the whole tour:
{
"mapMarker": "image"
}| Mode | Marker | Notes |
|---|---|---|
"number" (default) | Numbered circle; checkmark when completed | The original behaviour |
"image" | The stop's own photo, cropped into the circle | See below |
"empty" | Plain circle; checkmark still shown when completed | Like number with the number hidden |
Image markers
With mapMarker: "image", each marker shows that stop's image — the same photo used in the list — cropped into a 32 × 32 px circle. State is conveyed with a colored ring instead of a number:
| State | Appearance |
|---|---|
| Active (current stop) | Photo with a ring in mapMarkers.active.outlineColor |
| Completed | Photo with a ring in mapMarkers.completed.backgroundColor |
| Neither | Photo, no ring |
Stop has no image | Empty circle — never a broken image |
In the default themes the active and completed ring colors are both green (#459825), so they look identical until you give them distinct values in your theme.
Custom marker icons
Custom icons replace the circle entirely with your own image — no circle, ring, number, or checkmark. Set one for the whole tour with mapMarkerIcon in metadata.json:
{
"mapMarkerIcon": "https://api.iconify.design/ph/map-pin-duotone.svg"
}Or override a single stop's marker in the language file:
{
"id": "3",
"type": "audio",
"mapMarkerIcon": "https://api.iconify.design/ph/map-pin-plus-bold.svg"
}Icons are displayed at 32 × 32 px (object-fit: contain) inside a 44 × 44 px tap target.
Precedence
For each stop the marker is chosen in this order — first match wins:
mapMarkerIconon the stop — stop-level custom iconmapMarkerIconinmetadata.json— tour-level custom iconmapMarkermode —image/number/empty
Cluster icons are always unaffected.
Marker clustering
When stops are close together, AudioGuideKit can group them into cluster bubbles that expand as visitors zoom in:
{
"mapCluster": {
"disableClusteringAtZoom": 16,
"spiderfyOnMaxZoom": true
}
}| Field | Default | Description |
|---|---|---|
disableClusteringAtZoom | — | Zoom level where clustering stops |
spiderfyOnMaxZoom | true | Fan out overlapping markers at max zoom |
Route line
An optional polyline connects stops in sequence. It splits into two visual segments: solid for visited stops, dashed for stops still ahead — a progress indicator along the route.
The line only appears at street-level zoom (configurable via minZoom) and hides on overview zoom, keeping the map uncluttered.
Straight-line route
{
"mapRoute": true
}Draws straight lines between stop coordinates. Good for most situations.
Street-accurate route with GeoJSON
For tours where visitors walk along real streets, provide a GeoJSON file that follows the actual path:
{
"mapRoute": {
"geoJSON": "./route.geojson"
}
}Place the file next to metadata.json:
src/data/tour/
my-tour/
metadata.json
route.geojson
en.json
GeoJSON coordinates use [longitude, latitude] order — the reverse of the { lat, lng } objects used elsewhere. This is the GeoJSON standard, not a quirk.
Generating the file: Export a GPX track from Komoot, Google Maps, Strava, or any walking app, then convert it to GeoJSON at geojson.io.
Route configuration
| Field | Default | Description |
|---|---|---|
geoJSON | — | Relative path to a GeoJSON file |
minZoom | 13 | Hide the line below this zoom level |
Route colors and line styling are set via mapMarkers.route in your theme. See Theming for the full reference.
All metadata.json map fields
| Field | Type | Default | Description |
|---|---|---|---|
mapView | boolean | false | Show the map tab |
listView | boolean | true | Show the list tab |
mapProvider | string | "openstreetmap" | Tile provider |
mapStyleId | string | — | Provider-specific style ID |
mapCenter | { lat, lng } | — | Fixed starting center |
mapZoom | number | — | Fixed starting zoom (0–23) |
mapMarker | "number" | "image" | "empty" | "number" | Default marker style for the tour |
mapMarkerIcon | string | — | Custom icon URL for all markers; overrides mapMarker |
mapCluster | object | — | Clustering behaviour |
mapRoute | boolean | object | false | Route polyline with progress |
mapLocateButton | boolean | true | Show the locate-me button |
Offline behaviour
Map tiles require an internet connection. When the device is offline, the map is replaced with an "unavailable offline" message and a View list button.
Stop data, GPS coordinates, and audio files remain fully accessible offline — visitors can still navigate through the stop list.