Get started
Map Embedding

Iframe events

Iframe events

Beyond its initial configuration, Map Embedding speaks a small postMessage API. Your page sends commands into the iframe to switch the displayed content, and the embed posts a ready event back to your page once the map settles. Every message is an object with a type field prefixed mountaya:.

Sending commands

To change what the embed shows after it has loaded, post a message to the iframe's contentWindow. One command is available.

mountaya:setItinerary

command

Switch the map to an itinerary. The message carries itineraryId (a string) plus any of the optional display overrides below.

The command accepts optional display overrides alongside the id. Any field you include is applied; any you omit leaves the embed's current state unchanged. The override fields are camelCase: terrain, withOverlays and withTerrains (arrays of slugs), and the boolean toggles withDirectionsControl, withDownloadControl, withNavigationControl, withOverlaysControl, withPreferencesControl, withProfileAnalysis, withProfileCharacteristics, withProfileElevation, and withStreetviewControl.

Overrides respect your organization's safety rules, exactly as the iframe parameters do: a capability your organization has locked off for embeds stays off even if a command sets it, and the overlay and terrain lists are held to your organization's allowlists. The embed enforces this server-side.

A minimal command looks like this:

{
  "type": "mountaya:setItinerary",
  "itineraryId": "itinerary_123"
}

With overrides, switching content and changing the terrain in one message:

{
  "type": "mountaya:setItinerary",
  "itineraryId": "itinerary_456",
  "terrain": "satellite",
  "withOverlays": ["hillshade", "steepness"]
}

Post the message to the iframe's contentWindow, targeting the embed's origin (https://app.mountaya.com).

const iframe = document.querySelector("#mountaya");

iframe.contentWindow.postMessage(
  { type: "mountaya:setItinerary", itineraryId: "itinerary_123" },
  "https://app.mountaya.com",
);

Listening for events

The embed posts a mountaya:ready event to the parent window each time the map settles: on the initial load, and again after every mountaya:setItinerary content switch (or when a load ends in an error). Listen for it with a message handler and key on the message type.

The ready event always carries these fields:

type

string

Always "mountaya:ready". Key your handler on this so you ignore unrelated messages.

error

string | null

null on a clean load. Otherwise "timeout" if the map did not finish loading in time, or "not_found" if the requested content could not be resolved. The field is always present, so test error === null for success.

bounds

[number, number, number, number] | null

The framed itinerary's own geographic extent as [west, south, east, north] in WGS 84, not the padded viewport. It is null when no content frames the view, which includes a base-map-only embed and an itinerary that yields no extent, and also when the load ended in an error.

itineraryId

string | null

The active itinerary id, or null if none is displayed.

terrain

string

The resolved basemap terrain slug.

A successful ready event looks like this:

{
  "type": "mountaya:ready",
  "error": null,
  "bounds": [6.82, 45.8, 6.92, 45.95],
  "itineraryId": "itinerary_123",
  "terrain": "topo"
}

The embed posts the ready event with a wildcard target origin, so verify the message came from the Mountaya origin by checking event.origin before trusting it.

window.addEventListener("message", (event) => {
  if (event.origin !== "https://app.mountaya.com") {
    return;
  }

  if (event.data?.type !== "mountaya:ready") {
    return;
  }

  if (event.data.error) {
    console.error("Mountaya embed failed:", event.data.error);
    return;
  }

  console.log("Map ready, bounds:", event.data.bounds);
});

The full public protocol

mountaya:setItinerary and mountaya:ready are the whole protocol available to an embed on your own domain: one command in, one event out.

If you inspect the embed's traffic you may notice other mountaya: message types. They are internal to the Mountaya console — the embed answers them only when the sender shares its own origin, which your page never does. Posting one from your site is silently ignored rather than refused, so a request that seems to hang has not failed; it was never a message this embed answers. Build only on the two above.

Next steps