Deep links

Some places can show an iframe but cannot run your JavaScript: a SharePoint page, a Confluence macro, a link in an email. For those, the map's URL can carry the state it should open in. No SDK is involved.

<iframe src="https://embed.iconmap.ai/v/pub_...?bookmark=bm-north&f.region=EMEA&lang=de"
        style="width: 100%; height: 600px; border: 0"></iframe>

What a link can carry

In the URL Does
?bookmark=<id> Opens on one of the author's bookmarks
?f.<name>=<value> Sets a declared filter. Repeat for several filters
?lang=<code> Reader language, for example fr or de-DE
#s=<scene> Restores a whole captured scene: camera, visibility, slicers, filters, selection, basemap

When several are present they are applied in that order, so a scene has the last word.

Filter values

A plain value is taken as text. Anything else is written as JSON and URL-encoded:

?f.region=EMEA
?f.region=%5B%22EMEA%22%2C%22APAC%22%5D                         ["EMEA","APAC"]
?f.period=%7B%22operator%22%3A%22inLast%22%2C%22count%22%3A30%2C%22unit%22%3A%22days%22%7D

A name the author did not declare is ignored, exactly as it would be rejected through the API - a link can never filter on a column the author did not offer.

Why the scene is in the fragment

Everything after # stays in the browser: it is not sent to the server, so it never appears in access logs, proxies or analytics. A scene can hold a selection and filter values, which is reason enough to keep it out of them.

Building links

From the Publish dialog

After publishing, the dialog offers Copy link to this view next to the embed URL. It captures the editor's current camera, layer visibility and slicer selections as a scene and copies a link that opens the published map exactly there.

From your page

const { sceneToUrl } = IconMapEmbed;

const scene = await map.captureScene();

const link = sceneToUrl("https://embed.iconmap.ai/v/pub_...", {
  scene,
  bookmarkId: "bm-north",
  filters: { region: ["EMEA"] },
  language: "de",
});

Every part is optional. deepLinkFromUrl(url) is the inverse, if you want to read one back:

const { deepLinkFromUrl } = IconMapEmbed;
const { scene, bookmarkId, filters, language } = deepLinkFromUrl(location.href);

By hand

A scene is base64url-encoded JSON, so a link can be produced by anything that can do that - a server, a report, a script:

const scene = { v: 1, camera: { center: [-3.18, 51.48], zoom: 12, bearing: 0, pitch: 0 } };
const s = btoa(JSON.stringify(scene)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const link = `https://embed.iconmap.ai/v/pub_...#s=${s}`;

v and camera are required; everything else in a scene is optional.

Good to know

  • Links survive a re-publish of the same layers. Ids the map no longer has are skipped; the rest applies. A re-publish does mint a new publish id, so links to the old publish keep opening the old one until the author revokes it.
  • A deep link needs no allowed origin. Allowed origins govern who may drive a map from script. A link only sets the state the map opens in, using things any reader could do by hand.
  • Length. A scene with a large selection makes a long URL. Browsers cope with several thousand characters, but some chat and email tools truncate. Capture only what you need: captureScene({ include: ["camera", "visibility"] }).
  • With the SDK too. If your page uses the SDK, prefer the scene, bookmarkId, filters and language options - they do the same thing and are typed.