This is the documentation of version 0.54.0. Go to the latest version, 1.0.0-rc.5.

Routing module

The Routing Module enables displaying calculated routes and waypoints on maps with comprehensive functionality for visualizing navigation routes, alternative routes, turn-by-turn guidance, traffic incidents that occur along the calculated path, and route-related interactions.

Initialization

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

// Initialize map
const map = new TomTomMap({ mapLibre: { container: 'map' } });

// Initialize Routes module with default configuration
const routingModule = await RoutingModule.create(map);

// Or with custom configuration
const routingModule = await RoutingModule.create(map, {
    displayUnits: {
        distance: { type: 'metric' }
    },
    waypointsSource: {
        entryPoints: 'main-when-available'
    }
});

Displaying routes

Display calculated routes on the map:

import { calculateRoute, geocodeOne } from '@tomtom-org/maps-sdk/services';

// Calculate a route with coordinates
const route = await calculateRoute({
    locations: [
        [4.9041, 52.3676], // Amsterdam
        [4.4777, 51.9244]  // Rotterdam
    ],
});

// Or calculate a route with geocoded locations
const waypoints = await Promise.all([
    geocodeOne('Amsterdam, Netherlands'),
    geocodeOne('Rotterdam, Netherlands')
]);

const routes = await calculateRoute({ locations: waypoints });

// Show the route
await routingModule.showRoutes(route);

Note: showRoutes draws the route line but does not show waypoint markers (start, stop, destination pins). Call showWaypoints separately to display them — see Waypoints below.

Displaying guidance on map

Request guidance instructions when calculating a route to show them visually:

import { calculateRoute } from '@tomtom-org/maps-sdk/services';

const route = await calculateRoute({
    locations: [
        [4.9041, 52.3676], // Amsterdam
        [4.4777, 51.9244]  // Rotterdam
    ],
    guidance: {
        type: 'coded'
    }
});

// Display route with guidance on map
await routingModule.showRoutes(route);

Route selection

Change which route appears as selected when displaying multiple routes:

import { calculateRoute } from '@tomtom-org/maps-sdk/services';

// Calculate route with alternatives
const routes = await calculateRoute({
    locations: [
        [4.9041, 52.3676], // Amsterdam
        [4.4777, 51.9244]  // Rotterdam
    ],
    maxAlternatives: 2,
});

// Show the routes (first route selected by default)
await routingModule.showRoutes(routes);

// Show the routes with specific selection
await routingModule.showRoutes(routes, { selectedIndex: 1 });

// Switch to second route
await routingModule.selectRoute(1);

// Switch back to first route
await routingModule.selectRoute(0);

Waypoints

showRoutes only draws route lines — waypoint markers (start, stop, and destination pins) are not included. You must call showWaypoints separately:

const locations = [
    [4.9041, 52.3676], // Amsterdam
    [4.4777, 51.9244]  // Rotterdam
];

const route = await calculateRoute({ locations });

// Draw the route line
await routingModule.showRoutes(route);

// Waypoint markers must be shown separately
await routingModule.showWaypoints(locations);

// Clear waypoints independently from routes
await routingModule.clearWaypoints();

A stop's pin is labelled with its name, and — when the stop carries a pauseDurationSeconds — with how long the route waits there:

const locations = [
    [2.1734, 41.3851],
    {
        type: 'Feature',
        geometry: { type: 'Point', coordinates: [2.4467, 41.5381] },
        // the pin reads "30 min" under the stop name
        properties: { pauseDurationSeconds: 30 * 60 }
    },
    [2.8214, 41.9794]
];

await routingModule.showRoutes(await calculateRoute({ locations }));
await routingModule.showWaypoints(locations);

The wait is formatted with the SDK's display units, and the label is the routeWaypointLabel layer — restyle or replace it through layers.waypoints.routeWaypointLabel like any other routing layer.

Charging stop pins say the same thing in the same way: their label carries the whole time spent at the stop, which is the charging plus any wait asked for at the same place. A label that wants only the charging part can still read chargingDuration:

const routingModule = await RoutingModule.create(map, {
    chargingStops: { text: { title: ['format', ['get', 'chargingDuration'], {}] } }
});

For more control over marker appearance and behavior (custom icons, popups, click handlers), use the Places Module to render waypoints as place markers instead.

Custom styling

Customize route appearance through layer configuration:

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

// Override paint properties on specific route layers.
// Each entry under `layers` is keyed by layer group (mainLines, sections, …),
// and each layer accepts partial `paint`/`layout` overrides that are merged
// onto the SDK defaults.
const routingModule = await RoutingModule.create(map, {
    layers: {
        mainLines: {
            routeLine: {
                paint: {
                    'line-color': '#FF0000', // Red main route line
                    'line-width': 6
                }
            }
        }
    }
});

Charging stop icons

Long-distance EV routes place a charging stop at the end of each leg. Supply your own sprites with chargingStops.icon.customIcons, then pick one per stop with mapping:

const routingModule = await RoutingModule.create(map, {
  chargingStops: {
    icon: {
      customIcons: [
        { id: 'slow-charger', image: chargerSlowSVG },
        { id: 'fast-charger', image: chargerFastSVG, offsetX: 0, offsetY: -10 }
      ],
      mapping: {
        basedOn: 'chargingSpeed',
        value: { slow: 'slow-charger', regular: 'slow-charger', fast: 'fast-charger', 'ultra-fast': 'fast-charger' }
      }
    }
  }
});

mapping can also be { basedOn: 'custom', fn: (stop) => spriteID } for any other rule, and it works without customIcons if you only want to point at sprites the style already ships.

offsetX/offsetY (pixels) shift an icon from its coordinate, for icons whose visual tip isn't at their own geometric bottom. Positive offsetX moves right, positive offsetY moves down. They only apply to a customIcons entry that also provides an image — an entry naming an existing sprite by id alone ignores them.

Events

Handle user interactions with routes and waypoints:

// Route click events
routingModule.events.mainLines.on('click', (feature, lngLat) => {
    console.log('Route clicked:', feature.properties);
    console.log('Coordinates:', lngLat);
});

// Waypoint events
routingModule.events.waypoints.on('click', (feature, lngLat) => {
    console.log('Waypoint:', feature.properties);
});

// Traffic incident events
routingModule.events.incidents.on('hover', (feature, lngLat) => {
    console.log('Traffic delay:', feature.features.map(feature => feature.properties.delayInSeconds));
});

// Turn-by-turn instruction events
routingModule.events.instructionLines.on('click', (feature, lngLat) => {
    console.log('Instruction properties:', feature.properties);
});

// Summary bubble events
routingModule.events.summaryBubbles.on('click', (feature, lngLat) => {
    console.log('Route summary:', feature.properties);
});

// Route section events
routingModule.events.ferries.on('click', (feature, lngLat) => {
    console.log('Ferry section');
});

// The `tollRoads` overlay draws the `tollRoad` sections — every stretch that costs money to drive,
// per-use tolls plus vignette-only motorways and urban charge zones
routingModule.events.tollRoads.on('click', (feature, lngLat) => {
    console.log('Charged road section');
});

routingModule.events.tunnels.on('click', (feature, lngLat) => {
    console.log('Tunnel section');
});

routingModule.events.vehicleRestricted.on('click', (feature, lngLat) => {
    console.log('Vehicle restricted section');
});

routingModule.events.chargingStops.on('click', (feature, lngLat) => {
    console.log('EV charging station');
});

// Remove event listeners
routingModule.events.mainLines.off('click', handler);

Multiple module instances

You can create multiple independent instances of the Routing module, each with its own configuration and styling. This is useful for comparing different route types or displaying routes for multiple users.

// Create separate instances for different route types
const carRoutes = await RoutingModule.create(map, {
    customLayerSpec: {
        layers: {
            mainLines: [{ layerSpec: { paint: { 'line-color': '#2ECC71' } } }]
        }
    }
});

const truckRoutes = await RoutingModule.create(map, {
    customLayerSpec: {
        layers: {
            mainLines: [{ layerSpec: { paint: { 'line-color': '#E67E22' } } }]
        }
    }
});

// Each instance manages its own routes independently
await carRoutes.showRoutes(carRoute);
await truckRoutes.showRoutes(truckRoute);

Reading shown data

Use getShown() to retrieve all routing data currently displayed on the map. This returns the exact data previously passed to showRoutes() and showWaypoints():

const shown = routingModule.getShown();
console.log(`Showing ${shown.mainLines.features.length} routes`);
console.log(`Showing ${shown.waypoints.features.length} waypoints`);

Check whether any routes are currently displayed:

const shown = routingModule.getShown();
if (shown.mainLines.features.length > 0) {
    console.log('Routes are displayed');
}

The returned object includes: mainLines, waypoints, incidents, ferries, chargingStops, tollRoads, tunnels, vehicleRestricted, instructionLines, instructionArrows, and summaryBubbles.

API reference

For complete documentation of all Routing Module properties, methods, and types, see the RoutingModule API Reference.

Related guides and examples

Services integration

Related examples

Related map modules