Resolves the sources this scope's features are drawn in, on every call.
Takes the event state off one of this scope's features.
Takes the given event states, or all of them, off this scope's features.
Optionaloptions: CleanEventStatesOptionsThe ids of this scope's features that have an event state, by state.
Remove all event handlers for a specific event type.
Unregisters the callback function for the specified event type, stopping further event notifications. This is important for cleanup to prevent memory leaks and unwanted behavior.
The type of event to stop listening for
Cleanup Behavior:
When to Use:
off() then on())Best Practices:
// Remove click handlers
module.events.off('click');
// Remove all handlers
module.events.off('click');
module.events.off('hover');
module.events.off('long-hover');
module.events.off('contextmenu');
// React component cleanup
useEffect(() => {
const pois = map.pois();
pois.events.on('click', handlePoiClick);
pois.events.on('hover', handlePoiHover);
return () => {
// Cleanup on unmount
pois.events.off('click');
pois.events.off('hover');
};
}, [map]);
// Replace handler
module.events.off('click'); // Remove old handler
module.events.on('click', newHandler); // Add new handler
// Disable interactions temporarily
const savedHandler = currentHandler;
module.events.off('click'); // Disable
// ... later ...
module.events.on('click', savedHandler); // Re-enable
Register an event handler for user interactions with map features.
Attaches a callback function that will be invoked when users interact with features in this module (e.g., clicking on a POI, hovering over a route).
The type of event to listen for (click, contextmenu, hover, long-hover)
Callback function invoked when the event occurs
An unsubscribe function that removes the handler registered by this call.
Handler Parameters:
feature: The primary feature that triggered the eventlngLat: Geographic coordinates [longitude, latitude] of the eventfeatures: The features from this module at the event location, de-duplicated (for
overlapping features within the module). To inspect features across all modules, query
map.mapLibreMap.queryRenderedFeatures(...) directly — see UserEventHandler.Behavior:
on() adds a handler (it does
not replace existing ones) and all of them fire. To remove one, call the unsubscribe
this returns; to clear them all, use off(type).Performance:
// Basic click handler
module.events.on('click', (feature, lngLat, features) => {
console.log('Clicked feature:', feature.properties);
console.log('Location:', lngLat);
console.log('All features here:', features.length);
});
// Hover with tooltip
module.events.on('hover', (feature) => {
const name = feature.properties.name || 'Unnamed';
tooltip.show(name);
});
// Long-hover for detailed preview
module.events.on('long-hover', (feature) => {
// Only triggered after hovering for 300-800ms
loadPreview(feature.properties.id);
});
// Right-click context menu
module.events.on('contextmenu', (feature, lngLat) => {
event.preventDefault(); // Prevent browser context menu
showCustomMenu(lngLat, feature);
});
// Route-specific handlers
const routing = map.routing();
// Handle route line clicks
routing.events.mainLines.on('click', (route) => {
highlightRoute(route.properties.routeID);
showRouteSummary(route.properties.summary);
});
// Handle waypoint interactions
routing.events.waypoints.on('hover', (waypoint) => {
const index = waypoint.properties.index;
showTooltip(`Stop ${index + 1}`);
});
Puts an event state on one of this scope's features; see PutEventStateOptions.
Narrows these events to part of what they cover, returning a UserEvents over just that part.
Two things can be narrowed. A feature predicate keeps only the features you care about — available on every module, since only the module's own data can tell a major incident from a minor one. A layer scope keeps only part of the map's layers; the SDK offers this where a stable, typed vocabulary for those layers exists, which today means BaseMapModule's layer groups.
A new instance, rather than this one narrowed in place: callers hold events and narrow it
more than once, and mutating would make the second where() mean "first AND second" while
leaving the surface it came from silently scoped — and its config overridden.
Narrowing on both axes is one call, not two — BaseMapModule's scope object takes a
features predicate alongside its layerGroups. A further where() does intersect with
this one, but two feature predicates read better as a single a(f) && b(f).
See EventScope — a predicate over this scope's feature type, or, where
the module supports one, a scope object such as { layerGroups }.
Optionalconfig: EventHandlerConfig
Event configuration for handlers registered through the returned instance. Each scope can carry its own, which is how two parts of one module get different hover cursors. Defaults to the configuration this instance already uses.
// Feature scope: only major incidents are clickable.
trafficIncidents.events.where((incident) => incident.properties.magnitude === 'major')
.on('click', showIncidentDetails);
// Layer scope with its own cursor, on the base map.
baseMap.events
.where({ layerGroups: { show: 'only', values: ['roadLabels'] } }, { cursorOnHover: 'pointer' })
.on('click', showRoadName);
// A named scope, narrowed by a predicate.
routing.events.tunnels.where((section) => section.properties.lengthInMeters > 500)
.on('click', showLongTunnel);
A named events scope of a module that draws its own data: the UserEvents of one part of what the module shows, plus the event states of those features.
Remarks
The module's own
putEventState,cleanEventState,cleanEventStatesandgetEventStatesact on the features itsshowtakes; a scope's act on the scope's features alone, by the ids its handlers receive —routing.events.waypointson the waypoints,custom.events.<source>on one source. A UserEvents.where narrowing returns plain UserEvents: a state belongs to a feature, not to a predicate over features.Example