This is the documentation of version 1.0.0-rc.4. Go to the latest version, 1.0.0-rc.5.
TomTom Maps for JavaScript
    Preparing search index...

    Class TomTomMap

    The TomTom map, which displays interactive maps in web applications.

    It is the entry point for rendering TomTom maps. It wraps MapLibre GL JS with a simplified, enhanced API for common mapping tasks.

    It renders with MapLibre GL JS for high performance, and offers:

    • Seamless style switching without a map reload.
    • An integrated event handling system.
    • Multiple languages, switchable at runtime.
    • Geopolitical views of disputed borders and names, switchable at runtime.
    • Compatibility with TomTom map modules (traffic, POIs, routing, etc.).

    It exposes the underlying MapLibre Map instance as mapLibreMap, manages the map lifecycle and style transitions, and coordinates with map modules for data visualization.

    Basic map initialization:

    import { TomTomMap } from '@tomtom-org/maps-sdk/map';

    const map = new TomTomMap({
    apiKey: 'YOUR_API_KEY',
    style: 'streetLight',
    mapLibre: {
    container: 'map',
    center: [4.9041, 52.3676],
    zoom: 10
    }
    });

    With modules and configuration:

    const map = new TomTomMap({
    apiKey: 'YOUR_API_KEY',
    style: {
    type: 'standard',
    id: 'streetDark',
    include: ['trafficFlow', 'trafficIncidents']
    },
    language: 'en-US',
    events: {
    precisionMode: 'point-then-box',
    cursorOnHover: 'pointer'
    },
    mapLibre: {
    container: 'map',
    center: [-74.006, 40.7128],
    zoom: 12
    }
    });

    // Access MapLibre functionality directly
    map.mapLibreMap.on('load', () => {
    console.log('Map loaded');
    });
    Index
    • Constructs a new TomTom Map instance and attaches it to a DOM element.

      Parameters

      • mapParams: TomTomMapParams

        The combined TomTom and MapLibre parameters for map initialization, such as the API key, style, events and MapLibre options like container, center and zoom. TomTomMapParams lists them all.

      Returns TomTomMap

      The constructor:

      1. Merges mapParams with the global configuration.
      2. Creates the underlying MapLibre map instance.
      3. Loads the specified style asynchronously.
      4. Sets mapReady to true when complete.

      Parameters passed here override the global configuration, so each map can customize settings while sharing common ones.

      Minimal initialization:

      const map = new TomTomMap({
      apiKey: 'YOUR_API_KEY',
      mapLibre: {
      container: 'map',
      center: [0, 0],
      zoom: 2
      }
      });

      Full configuration:

      const map = new TomTomMap({
      apiKey: 'YOUR_API_KEY',
      style: {
      type: 'standard',
      id: 'streetLight',
      include: ['trafficFlow', 'terrain']
      },
      language: 'en-US',
      events: {
      precisionMode: 'point-then-box',
      paddingBoxPx: 10
      },
      mapLibre: {
      container: 'map',
      center: [-122.4194, 37.7749],
      zoom: 13,
      pitch: 45,
      bearing: -17.6,
      maxZoom: 18,
      minZoom: 8
      }
      });

      A TomTomMapError with code WEBGL_UNSUPPORTED when the browser cannot create a WebGL2 context, or INSECURE_BASE_URL when commonBaseURL is neither https: nor http: on a loopback address.

    mapLibreMap: Map$1

    The underlying MapLibre GL JS Map instance.

    Use it to access advanced MapLibre functionality TomTomMap doesn't expose, add custom layers, sources or controls, listen to MapLibre-specific events, or integrate third-party MapLibre plugins.

    It is available immediately after TomTomMap construction. Direct modifications may affect SDK module behaviour, so coordinate with SDK modules to avoid conflicts.

    Add custom layer:

    map.mapLibreMap.addLayer({
    id: 'custom-layer',
    type: 'circle',
    source: 'my-data',
    paint: {
    'circle-radius': 6,
    'circle-color': '#ff0000'
    }
    });

    Listen to events:

    map.mapLibreMap.on('moveend', () => {
    console.log('Camera position:', map.mapLibreMap.getCenter());
    });
    mapReady: boolean = false

    Whether the map style has fully loaded and is ready for interaction.

    It is true when the style is loaded and modules can be safely initialized, and false during map construction or style changes. Check it before style-dependent operations.

    if (map.mapReady) {
    // Safe to initialize modules
    const trafficFlowModule = await TrafficFlowModule.get(map);
    }
    • get mapColors(): Readonly<MapColors>

      The map's semantic colours as the StylingFoundationsModule last published them. These are the ten base-map colours in effect (a colors.* knob, or the style's own value), plus accent, the colour for what is drawn on top of the map. It is empty until a styling foundations module exists.

      Returns Readonly<MapColors>

      This is how a theme reaches the whole map. Routes, geometries and places default to accent when you chose no colour of your own, and follow it when it changes. A colour given explicitly always wins. Without an accent, each module keeps its own default.

      To set accent, call StylingFoundationsModule.setMapColors, typically with the map-theme plugin's deriveMapColors, or set the colors.accent knob.

      styling.setMapColors(deriveMapColors(['#1d3f8a', '#e63312', '#f5d000', '#f4f1ea'])); // map-theme plugin
      const routing = await RoutingModule.create(map); // routes draw in map.mapColors.accent
    • get styleLightDarkTheme(): LightDark

      Whether the loaded style draws a light or a dark map.

      Returns LightDark

      The SDK's own overlays read it to pick text and halo colours that stay legible over the base map. Bind your own UI to it rather than parsing the style ID. It follows from the style ID, so it is up to date as soon as you call setStyle.

      await map.setStyle('monoDark');
      document.body.classList.toggle('dark-mode', map.styleLightDarkTheme === 'dark');
    • Adds a MapLibre custom layer, such as a three.js scene, and keeps it in its place in the layer stack through every style change.

      Type Parameters

      Parameters

      Returns CustomLayer<HIT>

      The handle to the layer: its events, and remove() to take it off the map.

      Error when the map already has a layer with the same id, until that one's remove().

      • The layer goes on the map as soon as the map is ready, below the layer beforeLayerConfig names, and on top by default.
      • After every setStyle, before the modules restore themselves, it goes back to the same place, added again if the switch dropped it. The module layers then go back over or under it as they would if added after it.
      • With beforeLayerConfig: 'lowest3D', a 3D layer goes under the style's 3D buildings and shares their depth. Module layers placed at the same anchor or lower, such as before lowestLabel, stay under it, even the ones a module adds later.
      • With a hitTest, the layer's objects join the map's user events: a handler on the layer fires on the topmost object under the pointer, and nothing under it fires. The cursor and the hover and click states follow as on a module's features, with setState to draw the states.
      • Topmost goes by the layer stack, not by what is drawn in front: with a handler on the 3D buildings, a click on a 'lowest3D' object standing in front of a building goes to the building.
      • A screen-projection hit test also hits an object behind a 3D building: the hit tester owns the depth.
      const vehicles = map.addCustomLayer(vehiclesLayer, {
      beforeLayerConfig: 'lowest3D',
      hitTest: (point) => pickVehicles(point), // [{ id, properties }], topmost first
      setState: (id, state) => highlightVehicle(id, state),
      });
      vehicles.events.on('click', (vehicle) => inspector.show(vehicle));

      // Later, when the layer goes:
      vehicles.remove();
    • Registers a handler for every failure the map meets after construction, each as a TomTomMapError.

      Parameters

      Returns () => void

      A function that unregisters the handler.

      • A style that fails to load gets the code of the HTTP status it got (INVALID_CREDENTIALS, INSUFFICIENT_PERMISSIONS, RATE_LIMITED, …), NETWORK_NOT_AVAILABLE when no response arrived, otherwise STYLE_LOAD_FAILED. A setStyle switch also rejects with it, unless a newer one superseded it. Module creation and the module calls that wait for the map reject with it too, until a later setStyle loads a style.
      • A tile, sprite or glyph that fails to load gets the code of the HTTP status, NETWORK_NOT_AVAILABLE when no response arrived, otherwise INTERNAL. A tile's source is in sourceId. A tile answered with 404 isn't reported.
      • A lost WebGL context gets WEBGL_CONTEXT_LOST.
      • While no handler is registered, each failure is logged with console.error instead.
      • The constructor throws its own failures, WEBGL_UNSUPPORTED and INSECURE_BASE_URL, since no handler exists yet.
      const removeHandler = map.addErrorHandler((error) => {
      if (error.code === 'INVALID_CREDENTIALS') showMessage('The map could not load: check the API key');
      else if (error.code === 'INSUFFICIENT_PERMISSIONS') showMessage('The map could not load: check the APIs and domains the key allows');
      else if (error.code === 'WEBGL_CONTEXT_LOST') showMessage('The map stopped drawing: reload the page');
      });
    • Registers a handler to be notified when the map style changes.

      Parameters

      Returns () => void

      An unsubscribe function that removes this handler. Call it when the handler's owner (e.g. a custom overlay) is torn down. Otherwise, the handler and everything it closes over live for the lifetime of the map. It mirrors the disposer that module event handlers (module.events.on(...)) return.

      Use it when you have custom layers or sources to recreate after style changes, when your application responds to style switches (e.g. light/dark mode transitions), when you save and restore state during style changes, or when map modules need to reinitialize on style changes.

      The handler lifecycle is:

      1. onStyleAboutToChange() runs before the style change begins.
      2. The style changes.
      3. onStyleChanged() runs after the new style has fully loaded.

      You can register several handlers. They run by StyleChangeHandler.priority, lowest first, and in registration order where it is equal. The SDK awaits async callbacks one after the other, and the promise setStyle returns resolves once the last one has finished. It catches and logs each handler's errors independently, so one failing handler doesn't stop the others.

      Only setStyle calls trigger handlers, not the initial map construction. Handlers run for a clean switch as well as for one that carries state over, and their StyleChangeContext says which one it is. They persist for the lifetime of the TomTomMap instance unless unsubscribed.

      Basic usage:

      map.addStyleChangeHandler({
      onStyleAboutToChange: () => {
      console.log('Style is changing...');
      },
      onStyleChanged: () => {
      console.log('Style changed successfully!');
      }
      });

      // Later trigger the handlers
      map.setStyle('streetDark');

      Unsubscribe when the owner is torn down:

      const unsubscribe = map.addStyleChangeHandler({
      onStyleChanged: () => reattachCustomLayers(),
      });

      // Later, when the overlay is removed:
      unsubscribe();

      Preserve custom layers across style changes:

      let customLayerData: GeoJSON.GeoJSON | null = null;

      map.addStyleChangeHandler({
      onStyleAboutToChange: async () => {
      // Save custom layer data before style changes
      if (map.mapLibreMap.getLayer('my-custom-layer')) {
      customLayerData = await map.mapLibreMap.getSource<GeoJSONSource>('my-data')!.getData();
      map.mapLibreMap.removeLayer('my-custom-layer');
      map.mapLibreMap.removeSource('my-data');
      }
      },
      onStyleChanged: () => {
      // Restore custom layer after new style is loaded
      if (customLayerData) {
      map.mapLibreMap.addSource('my-data', {
      type: 'geojson',
      data: customLayerData
      });
      map.mapLibreMap.addLayer({
      id: 'my-custom-layer',
      type: 'circle',
      source: 'my-data',
      paint: { 'circle-radius': 6, 'circle-color': '#007cbf' }
      });
      }
      }
      });

      Async handler for external API calls:

      map.addStyleChangeHandler({
      onStyleAboutToChange: async () => {
      await saveStateToAPI(map.getStyleInput());
      },
      onStyleChanged: async () => {
      await loadStateFromAPI();
      }
      });

      Update UI based on style:

      map.addStyleChangeHandler({
      onStyleAboutToChange: () => {
      document.body.classList.add('style-changing');
      },
      onStyleChanged: () => {
      document.body.classList.remove('style-changing');
      const style = map.getStyleInput();
      if (typeof style === 'string' && style.includes('Dark')) {
      document.body.classList.add('dark-mode');
      } else {
      document.body.classList.remove('dark-mode');
      }
      }
      });
    • Retrieves the current visible map area as a GeoJSON bounding box.

      Returns BBox

      A GeoJSON BBox array in the format [west, south, east, north] representing the map's current viewport bounds.

      The array holds four numbers, [west, south, east, north], in WGS84 decimal degrees, as MapLibre reports the view: on a view across the antimeridian, east passes 180 rather than taking the west > east form of BBox. calculatePaddedBBox returns that form.

      Get current bounds:

      const bbox = map.getBBox();
      console.log('Bounds:', bbox);
      // Output: [-122.5, 37.7, -122.3, 37.8]
      // [west, south, east, north]

      Use bounds for spatial query:

      const results = await discoverPlaces({
      query: 'restaurants',
      geoBias: { boundingBox: map.getBBox() }
      });

      Save and restore map view:

      // Save current view
      const savedBounds = map.getBBox();
      const savedZoom = map.mapLibreMap.getZoom();

      // Later, restore the view
      const [west, south, east, north] = savedBounds;
      map.mapLibreMap.fitBounds([[west, south], [east, north]]);
    • Changes the geopolitical view of the map, meaning the borders and the territory and sea names it draws for disputed territories.

      Parameters

      • geopoliticalView:
            | "Unified"
            | "AE"
            | "AR"
            | "BN"
            | "CL"
            | "CN"
            | "DZ"
            | "IL"
            | "IN"
            | "KR"
            | "MA"
            | "MY"
            | "PH"
            | "PK"
            | "RS"
            | "RU"
            | "TR"
            | "TW"
            | "US"
            | "VN"
            | undefined

        The view to draw, or undefined for the default view of the country the map is viewed from. Set it at construction through core!GlobalConfig.geopoliticalView.

      Returns void

      • The visible tiles reload in place, and the view persists across every style change.
      • Applies to the TomTom Orbis vector tiles. The tiles do not serve CN and RU, which leave the default view. See core!GeopoliticalView.
      • Services keep the view of the global configuration, or of each call.
    • Changes the language of the map at runtime.

      To set the language at initialization, use the global config or TomTomMapParams instead.

      Parameters

      • language:
            | "ngt"
            | "ngt-Latn"
            | "ar"
            | "eu-ES"
            | "bg-BG"
            | "ca-ES"
            | "zh-Hant"
            | "zh-Hans"
            | "hr-HR"
            | "cs-CZ"
            | "da-DK"
            | "nl-NL"
            | "en-AU"
            | "en-CA"
            | "en-GB"
            | "en-NZ"
            | "en-US"
            | "et-EE"
            | "fi-FI"
            | "fr-FR"
            | "gl-ES"
            | "de-DE"
            | "el-GR"
            | "he-IL"
            | "hi-IN"
            | "hu-HU"
            | "id-ID"
            | "it-IT"
            | "ja-JP"
            | "kk-KZ"
            | "ko-KR"
            | "ko-Latn-KR"
            | "lv-LV"
            | "lt-LT"
            | "ms-MY"
            | "nb-NO"
            | "pl-PL"
            | "pt-BR"
            | "pt-PT"
            | "ro-RO"
            | "ru-RU"
            | "ru-Latn-RU"
            | "ru-Cyrl-RU"
            | "sr-RS"
            | "sk-SK"
            | "sl-SI"
            | "es-ES"
            | "es-MX"
            | "sv-SE"
            | "th-TH"
            | "tr-TR"
            | "uk-UA"

        The language for map translations.

      Returns void

      It updates all localizable map labels to the language, and falls back to the default label name where the language is unavailable. You can call it before or after the map has fully loaded. Before the map is ready, it applies once the style loads.

      The TrafficIncidentsModuleFeature descriptions follow it too, so it reloads the incident tiles when their language changes.

      The language can be any core!Language. Script variants such as 'zh-Hant' and 'ko-Latn-KR' label the map in that script.

      The language persists across every style change, a clean switch (SetStyleOptions.resetState) included. It is map configuration rather than SDK state, and this method is the only thing that changes it. To apply it immediately, set it at initialization through TomTomMapParams.language.

      Change language at runtime:

      // Switch to French
      map.setLanguage('fr-FR');

      Use script or regional variants:

      // Use Traditional Chinese
      map.setLanguage('zh-Hant');

      // Use Brazilian Portuguese
      map.setLanguage('pt-BR');

      Language switcher UI:

      const languageSelector = document.getElementById('lang-select');
      languageSelector.addEventListener('change', (e) => {
      map.setLanguage(e.target.value);
      });
    • Changes the map style dynamically without reloading the entire map.

      Parameters

      Returns Promise<void>

      A promise that resolves once the new style is loaded and every registered StyleChangeHandler has finished, including the SDK modules restoring themselves. Awaiting it is optional. Once it resolves, the map is safe to read and draw on again.

      A TomTomMapError if the style itself fails to load, leaving mapReady false and the map on the style it had: the code of the HTTP status it got, NETWORK_NOT_AVAILABLE when no response arrived, else STYLE_LOAD_FAILED. The error handlers get it too, and module creation and the module calls that wait for the map reject with it until a later switch loads a style. A tile or source that fails to load does not fail the switch. Called before the map's first style loaded, a failed switch finishes that style instead, and mapReady turns true.

      By default, the switch carries state over. It merges the previous style's parts with the new style and restores SDK module data and configuration (traffic, routes, POIs, etc.).

      A clean switch (resetState: true) applies exactly the style you passed, without merging previous style parts. SDK modules re-bind to the new style with default configuration and nothing shown. Use it for complete style resets.

      Both keep the map language, since it is configuration, not state. It survives every style change until setLanguage changes it.

      During the switch:

      • mapReady is false for the duration of the transition.
      • The SDK awaits every onStyleAboutToChange handler, then hands the new style to MapLibre.
      • Once the style has loaded, mapReady is back to true and the SDK awaits every onStyleChanged handler by StyleChangeHandler.priority.
      • A setStyle call made while another one is still in flight supersedes it. No onStyleChanged handler runs for the older call, and its promise resolves. A load it had already started ends first, so MapLibre can draw that style briefly; if it fails, only the error handlers hear of it.
      • Passing the style already loaded runs the whole lifecycle without reloading it. This is how resetState: true doubles as a reset of the SDK modules over the current style.

      Simple style change:

      // Switch to dark mode
      map.setStyle('streetDark');

      Wait for the switch to complete before drawing on the map:

      await map.setStyle('streetDark');
      // modules have restored themselves; map.mapReady is true again

      Style change with detailed configuration:

      map.setStyle({
      type: 'standard',
      id: 'streetLight',
      include: ['trafficFlow', 'terrain']
      });

      Clean style switch without state preservation:

      // Complete reset - removes all SDK layers and modules
      map.setStyle('streetDark', { resetState: true });

      With style change handlers:

      map.addStyleChangeHandler({
      onStyleAboutToChange: () => {
      console.log('Preparing for style change...');
      },
      onStyleChanged: () => {
      console.log('New style applied!');
      }
      });

      map.setStyle('streetDark');
    • Changes the map's user events configuration at runtime.

      Parameters

      • config: MapEventsConfig

        The changes to merge into the current configuration, which TomTomMapParams.events set at construction. Whatever it leaves out or sets to undefined keeps its value.

      Returns void

      A module's own events config still overrides the cursor and hoverGracePeriodMS for its features. A long hover or a grace period already running keeps the delay it started with.

      map.updateEventsConfig({ longHoverDelayOnStillMapMS: 600, hoverGracePeriodMS: 1000 });