Developers
Embed with the SDK
Add the hosted Maphere viewer, connect your own controls, and manage its lifecycle in JavaScript or React.
Install and configure
Obtain the approved private SDK artifact from Maphere. Install it in your application and pin the supplied version. This example assumes a TypeScript-capable application bundler. No access to the Maphere platform repository is required.
npm install ./maphere-sdk-0.0.0.tgz- Publish the map and enable website embeds in Share.
- Add your exact HTTPS website origin to the allowed websites. When developing against a local non-production Maphere server, HTTP is supported only on loopback hosts such as http://localhost:4178.
- Copy the SDK map ID and give the map container an explicit height. Your website’s Content Security Policy must allow https://maphere.app in frame-src.
Your first viewer
import { createMap } from "maphere-sdk";
// Your page needs <div id="map" style="height: 600px"></div>
// and <p id="map-status" role="status"></p>.
const status = document.querySelector("#map-status")!;
const map = createMap("#map", {
mapId: "33333333-3333-4333-8333-333333333333",
title: "Harbour Centre map",
});
map.on("error", () => {
status.textContent = "Map unavailable. Please reconnect.";
});
try {
const { map: info } = await map.ready;
status.textContent = info.name + " is ready.";
} catch {
map.destroy();
}
// Also call map.destroy() when your page/component is removed.
window.addEventListener("pagehide", () => map.destroy(), { once: true });The ready promise resolves with the map directory and initial state after the viewer initializes. It does not wait for every optional image, background tile or camera animation. Use the returned IDs for commands rather than hard-coded display names.
Build your own controls
// Continue with a ready map instance from the example above.
const { map: info } = await map.ready;
await map.setControls({ floors: false });
// Your page needs <label for="floor">Floor</label>
// and <select id="floor"></select>.
const select = document.querySelector<HTMLSelectElement>("#floor")!;
select.replaceChildren(...info.floors.map((floor) =>
new Option(floor.name, floor.id)
));
select.value = (await map.getState()).floorId;
select.addEventListener("change", () => {
void map.setFloor(select.value).catch(() => {
status.textContent = "Floor unavailable. Please reconnect.";
});
});
const stop = map.on("floorchange", ({ floorId }) => {
select.value = floorId;
});
// When removing the controls: stop();
// When removing the map: map.destroy();| Command | Effect |
|---|---|
| selectPlace(placeId) / selectPlace(null) | Select a place or clear the selection; selecting can switch floors. |
| setFloor(floorId) | Choose a floor; clear a selection that is absent from it. |
| setView("top" | "perspective") | Change the map view. Perspective has no visual effect in the 2D fallback. |
| camera("zoomIn" | "zoomOut" | "reset") | Adjust the camera. Pan and rotation commands are also supported. |
| setControls({ search, floors, camera, details }) | Show or hide selected built-in controls. |
| getState() | Read the acknowledged floor, selection, view and control state. |
Listen for selectionchange, floorchange and statechange to keep your interface synchronized. map.on returns an unsubscribe function. Commands return acknowledged state; relative commands such as zoom must not be blindly repeated after a timeout.
React and Next.js lifecycle
"use client";
import { useEffect, useRef, useState } from "react";
import { createMap } from "maphere-sdk";
export function VenueMap({ mapId }: { mapId: string }) {
const container = useRef<HTMLDivElement>(null);
const [message, setMessage] = useState("");
useEffect(() => {
if (!container.current) return;
setMessage("");
const map = createMap(container.current, { mapId });
const off = map.on("error", () => setMessage("Map unavailable."));
void map.ready.catch(() => {}); // The error event updates the UI.
return () => { off(); map.destroy(); };
}, [mapId]);
return <>
<div ref={container} style={{ height: 600 }} />
<p role="status">{message}</p>
</>;
}Create the map in an effect after its DOM container is connected. Always remove event listeners and destroy it during cleanup. This supports React Strict Mode’s mount/cleanup cycle. For protected maps, keep the token callback stable between renders. The server SDK belongs only in your backend.
Recover and test
- Provide an accessible status region and a reconnect action when a map cannot load.
- An iframe reload or access failure ends the current connection. Destroy it and create a new instance after checking access; use the new ready directory.
- Check desktop and narrow mobile layouts, keyboard use, lost network access and the 2D fallback. Camera rotation and perspective do not change the 2D fallback.
- Keep attribution visible. The SDK supplies control of a hosted map, not ownership of third-party data or an offline export.