Events
Events tell your page what is happening in the map. They are opt-in: the map sends nothing until you subscribe, so an embed that only displays a map costs nothing extra.
Subscribing
const stop = map.on("viewChanged", (view) => { /* ... */ });
stop(); // remove this handler
map.off("viewChanged"); // remove every handler for the event
You can subscribe before the map is ready, and you can name events at mount so nothing is missed during start-up:
embed(el, { publishId, events: ["rendered", "featureClick"] });
Subscriptions survive map.reload().
reason: avoiding echo loops
If your page and the map mirror each other - a list that follows the map, a URL that stores the view - each of your own commands comes back to you as an event. Without care, that loops.
Every state event therefore says why it happened:
reason |
Meaning |
|---|---|
user |
The reader did it - dragged, clicked, used a control in the map |
command |
Your page did it, through the API |
bookmark |
A bookmark was applied |
tour |
A playing tour did it |
scene |
applyScene did it |
load |
Initial state while the map starts |
So a two-way sync is one line:
map.on("viewChanged", (v) => { if (v.reason === "user") writeViewToUrl(v); });
The events you will use most
viewChanged
Fires when the camera settles, with the same shape getView() returns plus reason. By default you get one event per gesture, at most every 200 ms. Both are adjustable:
embed(el, { publishId, events: ["viewChanged"], subscribeOptions: { viewChangedThrottleMs: 500 } });
embed(el, { publishId, events: ["viewChanged"], subscribeOptions: { continuousView: true } }); // while moving, too
The last position always arrives, however fast the reader moves.
featureClick
map.on("featureClick", (f) => {
if (!f) return closeMyPanel(); // the reader clicked empty map
// f = { layerId, layerName, featureKey, fields, lngLat }
});
fields holds the fields the layer shows in its tooltip - what the reader can already see - and nothing else. If you need another column to join on, ask the map's author to add it to the layer's tooltip. featureKey is stable for the life of the publish and is what selectByKey and highlight accept.
featureHover has the same shape and null when the pointer leaves. It is spaced at least 100 ms apart; a leave is never delayed, so you will not be left believing the pointer is still over something.
selectionChanged, slicerChanged, filtersChanged, visibilityChanged
Each carries the new state and a reason. Use them to keep your own controls honest when the reader uses the map's:
map.on("visibilityChanged", ({ visibility }) => {
for (const [id, on] of Object.entries(visibility.layers ?? {})) myToggles[id].checked = on;
});
linkClicked
Maps can contain hyperlinks and link buttons. By default a click navigates. To handle it inside your application instead, set the behaviour at mount:
const map = embed(el, { publishId, hyperlinkBehavior: "raiseEvent", events: ["linkClicked"] });
map.on("linkClicked", ({ url, layerId, featureKey, buttonId }) => router.push(toMyRoute(url)));
"navigateAndRaiseEvent" does both.
menuCommandTriggered
Raised when the reader chooses an action you added with addMenuCommand.
analysisResult
Raised when an analysis operation completes, whether your page ran it or the reader did. See Analysis.
loaded, rendered, dataStateChanged
loaded means the map is up; rendered means its first frame is on screen, with durationMs from the frame's start - useful for your own performance monitoring. dataStateChanged reports live data loading, ready, stale or error.
tokenExpiring
For token-gated maps, fires a minute before the embed token expires. Answer with setToken. See Getting started.
error
Problems after the session opened. Start-up failures go to the onError option instead, and make ready reject.
Ordering and dropped events
Every event carries a seq that increases by one for the life of the session. The SDK handles it for you; it matters only if you log events and see a gap, which means one was dropped. The map drops an event rather than send a broken one in exactly one case: a payload over 32 KB.
The sequence restarts when the frame reloads.
The full list
Every event, with its payload type, is in the API reference. The map also tells you which events it can raise in capabilities.events.