Mount the studio props
The generated props of every element on Mount the studio. The guide is where they are explained; this is the whole surface.
MountayaStudio
mapClientMountayaMapOptions["client"]
The client the map draws through.
Omitted, it is the HOST's client, which is the right answer wherever one credential serves both the reads and the tiles. State it where the map's does not match (a signed-in studio that rides a session cookie for tiles and a key for everything else), and the two halves stay independent.
Whichever client ends up here is also what the tile transform is DERIVED from: its browser-safe credential, its tile-API origin, its language. That is why the two are separate props rather than one seam and why neither is required: see transformRequest below.
Its credential is held to the host's rule: under a host rendering the Embedded Studio (the default), a publishable key given no session token, and a session token minted for another surface than studio-embedded, are refused with a configuration error before the map draws a tile; a share token and the browser's own session are taken, and under a host declaring data.surface: "embedding" (Mountaya's hosted embed) a key with any session, or none, is accepted. While its session's first token is on its way, the map is not built, so none of its requests goes out without the token; the host waits the same way for its own client only.
transformRequestTileRequestTransform
Overrides the transform that stamps a credential onto each tile request.
Omitted, the map derives one from whichever client is drawing it: its browser-safe credential, its tile-API origin as the ONLY host allowed to receive that credential, and its language. That derivation is narrower than anything a caller would write by hand: it follows a client repointed at a local stack or a proxy, where a hand-written origin would keep naming the public host and silently authenticate nothing.
Supply one for what the credential projection cannot know: a share token scoped to a single path prefix, a surface=published opt-in, an origin the client does not speak to. createTransformRequest from @mountaya/elements builds it, and takes scoped and next for exactly those cases.
A secret-key client projects no credential at all, so the derived default authenticates as nobody rather than putting a server-side key on a map.
demTilesUrlstring
The terrain tiles the base map bakes its relief from, as a TileJSON or XYZ template.
A URL rather than a provider, because every DEM source this speaks to is one of those two, and which one serves elevation (under whose key) is the host's answer.
The answers, most explicit first: this prop, then the host's assets.demUrl, then the layers manifest's own elevation. Set none of them and the map renders flat rather than firing a request that cannot succeed.
configStudioConfig
Which controls the studio offers, and which terrains and overlays it may show.
It is a prop rather than something the studio resolves because both halves of the resolution are the host's: whose stored defaults apply, and which terrains and overlays their viewers are offered. Spread the default and narrow what you mean to narrow.
preserveDrawingBufferboolean
Whether the map's WebGL context preserves its drawing buffer.
Keep it off unless something reads the canvas out of band (a session recorder, a screenshot service): preserving the buffer costs a copy per frame on every pan.
constraintsStudioConstraintResolver
The camera's limits: a zoom floor and ceiling, and a boundary it may not leave.
A RESOLVER rather than a value, so the host keeps which organization is authoritative and how a geofence is spelled on its wire. Omitted, the camera is unconstrained.
urlStudioUrlSeam
The slice of the host's URL the studio mirrors its map state into, and restores it from on mount.
Two answers, most explicit first: this prop, then the host's behavior.url, the seam the verbs write through. A host that states the seam on MountayaStudioHost states it once. With neither, the studio still works and does not survive a reload: the terrain, the overlay, the enrichments and the time offset are held in the store alone.
collabEngineCollabEngine | null
The live collaboration session for the open itinerary.
Separate from the zone's, because the two resources are edited through different tools and a reader can hold a lock on one while another holds the other. Omitted, the editor works exactly as it does for a single author.
zoneCollabEngineCollabEngine | null
The live collaboration session for the open zone.
The zone half of the pair above, and independent of it for the same reason. Omitted, zone editing works exactly as it does for a single author.
googleMapsApiKeystring
The Google Maps key the Street View surfaces probe coverage and open a panorama with.
Omitted, the pegman and the context menu's Street View action are not offered, which is the honest absence: a control that opens nothing is worse than one that is not there.
streetViewHandleReactNode
The draggable handle a reader drops onto the map to open Street View.
elevationPanel(collapsed: boolean) => ReactNode
The elevation panel, drawn inside the studio's own docked sheet.
A render prop rather than a node, because the sheet resolves how much room the panel has from the live geometry around it (an open floating panel collapses the profile to its stat bar), and that answer is the studio's to make and the panel's to obey.
modalsReactNode
The host's own portalled surfaces, mounted inside the studio's element context so they read the same glyphs, copy and map.
Rendered unconditionally: whether a wizard's chunk is loaded is the host's decision, and every one of these gates on a store slot the host can read through useUiStore.
MountayaStudioViewer
embedConfigEmbedConfig
What the viewer is showing, fully resolved: the itinerary or collection, the terrain and overlay it opens on, which controls and profile sections it offers, and the reader's language. The host resolves it (from a publishable key, a URL, its own stored defaults, or all three), and this surface derives the control config and seeds the display state from it through the bus.
mapClientMountayaMapOptions["client"]
The client the map draws through, which the tile transform is derived from unless transformRequest states one.
Both must authenticate as the SAME audience. The point of a viewer is that what a publisher previews is what a visitor gets, and a client reading as the owner behind a transform reading as a visitor breaks exactly that, silently, because each half works.
Its credential is held to the host's rule: under a host rendering the Embedded Studio (the default), a publishable key given no session token, and a session token minted for another surface than studio-embedded, are refused with a configuration error before the map draws a tile; a share token and the browser's own session are taken, and under a host declaring data.surface: "embedding" (Mountaya's hosted embed) a key with any session, or none, is accepted. While its session's first token is on its way, the viewer shows its cover alone: no map is built, no read is made and no ready event is posted until the token lands, so none of its requests goes out without the token, and the ready deadline counts from then.
safetyRulesEmbedSafetyRules
The security boundary a runtime override is re-clamped to.
A viewer inside an iframe accepts configuration from the page around it, so it folds those overrides over embedConfig and clamps the result to the SAME rules the host applied when it resolved the config. Omitted, no override is accepted, which is the right answer for a surface nobody outside can reconfigure.
publishedSurfaceboolean
Read the PUBLISHED snapshot rather than whatever the credential would otherwise resolve to.
A visitor's credential already selects the publication, so a real viewer leaves this off. A PREVIEW does not: it authenticates as the owner in order to open at all, and would otherwise read the editor's draft. It must move in lockstep with the tile transform's option of the same name: one without the other paints draft geometry under a published elevation profile, or the reverse.
It also selects the snapshot a collection's specification is read for, whose extent a collection embed opens on. That read goes through the client rather than the transform, so this is what keeps the extent on the itineraries the tiles draw. The docked profile is handed the same snapshot as its surface option, so the reader's pace re-times the published route.
studioConfigStudioConfig
Override which controls the surface offers.
Omitted, they are derived from embedConfig: the publisher's own toggles, which is what a third-party embed should honour. A first-party surface passes its own resolved config instead, so a shared view offers what that host offers rather than what an arbitrary publisher enabled.
transformRequestTileRequestTransform
Override the transform that stamps a credential onto each tile request.
Omitted, the map derives one from the client drawing it: MountayaStudioProps documents the derivation and when a surface has to state its own.
watermarkReactNode
A mark drawn over the map, for a surface that carries attribution.
A NODE rather than a flag, because whose mark it is and what it says are the host's, and a package shipping a brand would be shipping the wrong one. It is not the tile credits: those are a licence obligation the map draws itself, on every surface, always.
cover(visible: boolean) => ReactNode
The cold-load cover, told whether it should still be showing.
A render prop because the studio owns the TIMING (the cover comes down when the constraints hook reports the initial view framed, with a timeout backstop), and the host owns what is drawn until then. Without one the map's default centre is visible for the moment before the framing lands.
tilesRequiredOverlayReactNode
What to draw over the map while the API refuses its tiles (a 401, a 402 or a 403).
A page served to visitors passes a neutral state that names nothing to do, as a share link and an embed do; a signed-in host may pass its own sign-in. Omitted, the map stays empty.
elevationPanel(options: ViewerProfileOptions) => ReactNode
The docked elevation profile, drawn inside the viewer's own sheet.
A render prop rather than a node: which sections it shows comes from the config, and how much room it has is resolved from the live geometry around it, so both are the studio's to decide and the panel's to obey.
streetViewHandleReactNode
The draggable handle a reader drops onto the map to open Street View.
googleMapsApiKeystring
The Google Maps key the Street View surfaces probe coverage and open a panorama with.
modalsReactNode
The host's own portalled surfaces, mounted inside the viewer's element context so they read the same glyphs, copy and map. Rendered unconditionally: whether a chunk is loaded is the host's decision, and each of these gates on a store slot it can read.
demTilesUrlstring
The terrain tiles the relief is baked from.
The answers, most explicit first: this prop, then the host's assets.demUrl, then the layers manifest's own elevation. Set none of them and the map renders flat rather than firing a request that cannot succeed.
preserveDrawingBufferboolean
Whether the map's WebGL context preserves its drawing buffer: off unless something samples the canvas out of band, because it costs a copy per frame on every pan.
zoomRangeEmbedZoomRange
The zoom floor and ceiling the viewer locks its camera to.
REQUIRED, while both ends of it are optional, and the pair is deliberate: how far into a published view a reader may zoom is the publisher's answer and never this package's, so a host states it, and {} is how a host states that there is no clamp. An optional prop would let a surface reach a reader without anyone having decided.
MountayaStudioHost
assetsStudioAssetsConfig
Where the pictures come from: the glyph tables, the relief raster, the activity and layer thumbnails and the routing guide's pictures.
appearanceStudioHostAppearanceConfig
What it looks like: the scheme, the density, the tokens, the theme, the canvas paint.
behaviorStudioHostBehaviorConfig
What it does, and what you do instead: handlers, seams, confirm, notify, the routers.
childrenReactNode
What the studio mounts inside every provider it wires: a MountayaStudio, a MountayaStudioViewer, or surfaces you have arranged yourself.
clientMountaya
The client every read and write beneath this host runs on.
Top-level rather than in data, because it is the one thing a studio cannot be mounted without and the first thing a consumer types. Omitted, the host reads the MountayaProvider above it and throws if there is none: a missing credential is a configuration error, not a studio that renders empty.
dataStudioHostDataConfig
What the studio is showing, and to whom: the catalog, the grants, the store, the viewer.
i18nStudioI18nConfig
Which words, and which regional conventions: the language, the locale, both bundles.
itineraryIdstring | null
The itinerary the studio opens, null to clear it, omitted to leave activation to a surface below.
Top-level beside client for the same reason: it is the other half of the shortest useful call, and a studio with a credential and no itinerary is a studio waiting for one.
pluginsStudioPluginsConfig
What a third party ADDS to it: the plugins to install, where a failure goes, the engine.
StudioHostRegistryProvider
childrenReactNode
The surfaces that register into the registry.
registryStudioHostRegistry
The registry the surfaces beneath read and register into, in place of a host's.
ShareViewModal
namestring
openedboolean
shareTokenstring
targetShareLinkTarget
stringsShareViewModalStrings
Overrides the words this surface says, for this surface only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone, and carried down to the rows and pickers this surface mounts. Scoped to the sections it renders: a key it never says is a type error rather than a silent no-op.
Handlers
An on* handler suppresses the element's own default. Left unset, the element acts; set, it becomes presentational and your handler decides. The two never both fire.
MountayaStudioViewer
onReady(payload: Omit<ReadyMessage, "type">) => void
onReady fires each time the initial view settles, on a cold load and again on every content switch, carrying what an iframe host needs to size and identify what it is showing. A viewer mounted inside an iframe posts it to the parent page; one rendered on a page of its own omits it, because there is nobody to notify. One that throws stops nothing: the view has settled and the cover has lifted by then, and its fault is raised on a microtask, where the page's own error handling sees it.
ShareViewModal
onClose() => void