Map styles

Map Styles in the TomTom Maps SDK define the visual appearance and data presentation of maps. This guide covers TomTom’s built-in styles, style components, and customization options.

A map style consists of various layers and sources that determine how geographic features are rendered.

The SDK provides several pre-defined styles optimized for different use cases, along with the ability to customize styles by including additional layers or modifying existing ones.

import { TomTomConfig } from '@tomtom-org/maps-sdk/core';
import { type StandardStyleID, standardStyleIDs, TomTomMap } from '@tomtom-org/maps-sdk/map';
import './style.css';
import { API_KEY } from './config';
import { initTogglePanel } from './togglePanel';

TomTomConfig.instance.put({ apiKey: API_KEY, language: 'en-GB' });

const map = new TomTomMap({
    mapLibre: {
        container: 'sdk-map',
        zoom: 14,
        center: [-0.12621, 51.50394],
    },
});

const stylesSelector = document.querySelector('#sdk-example-mapStyles') as HTMLSelectElement;
standardStyleIDs.forEach((id) => stylesSelector.add(new Option(id)));
stylesSelector.addEventListener('change', (event) =>
    map.setStyle((event.target as HTMLOptionElement).value as StandardStyleID),
);

initTogglePanel();

Built-in Styles

Basic Styles

import { TomTomMap } from '@tomtom-org/maps-sdk/map';
// Light theme (default)
const map = new TomTomMap({
mapLibre: {
container: 'map'
},
style: 'monoLight'
});
// Dark theme
const map = new TomTomMap({
mapLibre: {
container: 'map'
},
style: 'monoDark'
});
// Satellite imagery with roads
const map = new TomTomMap({
mapLibre: {
container: 'map'
},
style: 'hybrid'
});
// Pure satellite imagery
const map = new TomTomMap({
mapLibre: {
container: 'map'
},
style: 'satellite'
});

Dynamic Style Switching

const map = new TomTomMap({ mapLibre: { container: 'map' } });
// Change style after map creation
map.setStyle('monoDark');
// ...
map.setStyle('drivingLight');

Listening to Style Changes

Use addStyleChangeHandler to react when a style transition triggered by map.setStyle() begins or completes. This is the right hook for preserving custom layers, syncing UI state, or reinitializing anything that depends on the current style.

:::note This handler only fires for setStyle calls on TomTomMap. It does not fire on initial map construction. For lower-level style lifecycle hooks — such as reacting to the initial style load or to any style-related MapLibre event — use map.mapLibreMap.on('styledata', ...) directly. :::

import { TomTomMap, type StyleChangeHandler } from '@tomtom-org/maps-sdk/map';
const map = new TomTomMap({ mapLibre: { container: 'map' } });
map.addStyleChangeHandler({
onStyleAboutToChange: () => {
// Called before the style change begins — clean up anything tied to the current style
},
onStyleChanged: () => {
// Called after the new style is fully loaded — restore state, re-add layers, update UI
},
});

Both callbacks are optional. Use only the one(s) you need.

Preserving custom MapLibre layers

Custom sources and layers added via map.mapLibreMap are removed when the style changes. Use onStyleAboutToChange to save their data and onStyleChanged to restore them:

let savedData: GeoJSON.FeatureCollection | null = null;
map.addStyleChangeHandler({
onStyleAboutToChange: () => {
const source = map.mapLibreMap.getSource('my-data') as maplibre.GeoJSONSource | undefined;
if (source) {
savedData = source._data as GeoJSON.FeatureCollection;
}
},
onStyleChanged: () => {
if (savedData) {
map.mapLibreMap.addSource('my-data', { type: 'geojson', data: savedData });
map.mapLibreMap.addLayer({
id: 'my-layer',
type: 'circle',
source: 'my-data',
paint: { 'circle-radius': 6, 'circle-color': '#007cbf' },
});
}
},
});

Updating UI based on the active style

map.addStyleChangeHandler({
onStyleChanged: () => {
const style = map.getStyle();
const isDark = typeof style === 'string'
? style.toLowerCase().includes('dark')
: style?.id?.toLowerCase().includes('dark') ?? false;
document.body.classList.toggle('dark-mode', isDark);
},
});

Async handlers

Both callbacks can be async. The SDK awaits each one before continuing:

map.addStyleChangeHandler({
onStyleAboutToChange: async () => {
await persistStateToServer(map.getStyle());
},
onStyleChanged: async () => {
await restoreStateFromServer();
},
});

Available Style Parts

The map style includes multiple parts that come from different data sources:

  • Base Map and POIs: Core geographic features and points of interest.
  • Traffic Incidents: Real-time traffic incident data.
    • Included in the style by default, but hidden upfront.
    • Can be optionally excluded from the style for performance.
    • Controlled by TrafficIncidentsModule .
  • Traffic Flow: Live traffic flow information.
    • Included in the style by default, but hidden upfront.
    • Can be optionally excluded from the style for performance.
    • Controlled by TrafficFlowModule .
  • Hillshade: Terrain elevation shading for enhanced topography.
    • Included in the style by default, but hidden upfront.
    • Can be optionally excluded from the style for performance.
    • Controlled by HillshadeModule .
// Common layer modules you can include or not:
include: [
'trafficIncidents', // Traffic incidents
'trafficFlow', // Traffic flow data
'hillshade' // Terrain shading
]

Map Language

const map = new TomTomMap({
mapLibre: {
container: 'map'
},
style: 'monoLight',
language: 'de-DE' // German labels
});
);

Core Map Setup

Advanced Features

Practical Examples

Integration and Customization