Examples

These recipes combine the iframe configuration from the parameters page with the runtime postMessage API. Each is self-contained: drop it onto a page, replace the publishable key and ids, and adapt the markup to your framework.

Switch the displayed itinerary

A common pattern is a list of itineraries beside the map, where clicking one swaps the map's content without reloading the iframe. Post a mountaya:setItinerary command to the iframe's contentWindow on each selection. Wait for the mountaya:ready event before enabling the controls, so the first command is never posted too early.

<div class="itinerary-picker">
  <button data-itinerary="itinerary_alpha" disabled>Alpine traverse</button>
  <button data-itinerary="itinerary_beta" disabled>Lake loop</button>
</div>

<iframe
  id="mountaya"
  src="https://app.mountaya.com/studio/embed?publishable_key=pk_your_publishable_key&terrain=topo"
  title="Mountaya map"
  width="100%"
  height="520"
></iframe>

<script>
  const origin = "https://app.mountaya.com";
  const iframe = document.querySelector("#mountaya");
  const buttons = document.querySelectorAll(".itinerary-picker button");

  // Enable the picker only once the embed reports ready.
  window.addEventListener("message", (event) => {
    if (event.origin !== origin || event.data?.type !== "mountaya:ready") {
      return;
    }

    for (const button of buttons) {
      button.disabled = false;
    }
  });

  for (const button of buttons) {
    button.addEventListener("click", () => {
      iframe.contentWindow.postMessage(
        { type: "mountaya:setItinerary", itineraryId: button.dataset.itinerary },
        origin,
      );
    });
  }
</script>

You can carry display overrides on the same command, for example switching the terrain or the visible overlays as the content changes. See the events page for the full override list.

React to the ready event's bounds

The mountaya:ready event reports the map's viewport bounds as [west, south, east, north]. Use them to drive your own layout: render a caption with the extent, fit a static minimap, or note the active content id. This recipe reads the bounds and the active itinerary from the ready event and shows them beside the map.

<iframe
  id="mountaya"
  src="https://app.mountaya.com/studio/embed?publishable_key=pk_your_publishable_key&itinerary_id=itinerary_alpha"
  title="Mountaya map"
  width="100%"
  height="520"
></iframe>
<dl id="readout"></dl>

<script>
  const origin = "https://app.mountaya.com";
  const readout = document.querySelector("#readout");

  window.addEventListener("message", (event) => {
    if (event.origin !== origin || event.data?.type !== "mountaya:ready") {
      return;
    }

    if (event.data.error) {
      readout.textContent = "Map failed to load: " + event.data.error;
      return;
    }

    const bounds = event.data.bounds ? event.data.bounds.join(", ") : "unavailable";
    readout.innerHTML =
      "<dt>Terrain</dt><dd>" + event.data.terrain + "</dd>" +
      "<dt>Itinerary</dt><dd>" + (event.data.itineraryId ?? "none") + "</dd>" +
      "<dt>Bounds</dt><dd>" + bounds + "</dd>";
  });
</script>

Next steps