Embed the full SeatLayer Designer in your CMS without creating a SeatLayer login for every organizer. Your server owns tenancy and mints a short-lived session; the SDK owns iframe lifecycle and message validation.
End-to-end flow
- Create or select a chart in the organizer workspace.
- Authorize the current host user and decide their Designer authority.
- Mint a
dse_…session from your backend. - Mount the returned
designerUrl. - React to saved, published, close, and error events.
- Replace the session before or after expiry.
- Revoke it when access ends.
Mint from the server
export async function createDesignerSession(input: {
workspaceId: string;
chartId: string;
allowedOrigin: string;
}) {
const response = await fetch(
"https://api.seatlayer.io/v1/designer/sessions",
{
method: "POST",
headers: {
authorization: `Bearer ${process.env.SEATLAYER_SECRET_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
...input,
authority: "edit",
mode: "safe",
expiresInSeconds: 3600,
}),
},
);
if (!response.ok) throw new Error("Unable to open Designer");
return response.json();
}Use read-only for review, edit for draft work, or publish only when the host
user is allowed to release a chart. Safe mode is a useful default for delegated
venue editors.
Mount with JavaScript
import { EmbeddedDesigner } from "@seatlayer/js";
let editor;
async function mountDesigner() {
const { session } = await fetch("/api/designer-session", {
method: "POST",
}).then((response) => response.json());
editor = new EmbeddedDesigner({
container: "#designer",
designerUrl: session.designerUrl,
expectedChartId: session.chartId,
expectedWorkspaceId: session.workspaceId,
height: "fill",
minHeight: 560,
showLoadingState: true,
onReady: () => markEditorReady(),
onSaved: (message) => saveHostRevision(message.chartId),
onPublished: (message) => refreshChart(message.chartId),
onClose: () => closeEditor(),
onError: (message) => reportSafeError(message.code),
onRequestRelaunch: async () => {
const next = await fetch("/api/designer-session", {
method: "POST",
}).then((response) => response.json());
editor.setDesignerUrl(next.session.designerUrl);
},
});
editor.mount();
}height: "fill" detects whether the container has a definite height. It fills
that box or uses the remaining viewport height, with a minimum of 480 by
default. A numeric height opts into fixed-pixel behavior and legacy resize
messages.
React
import { EmbeddedDesigner } from "@seatlayer/react";
export function VenueEditor({ session, relaunch }) {
return (
<EmbeddedDesigner
designerUrl={session.designerUrl}
expectedChartId={session.chartId}
expectedWorkspaceId={session.workspaceId}
onSaved={({ chartId }) => refreshVenue(chartId)}
onPublished={({ chartId }) => activateRevision(chartId)}
onRequestRelaunch={relaunch}
/>
);
}Message safety
The SDK accepts only documented seatlayer.designer.* messages from the exact
iframe window and Designer origin. expectedChartId and
expectedWorkspaceId add host-side resource checks.
| Event | Host response |
|---|---|
ready |
Remove outer loading state |
saved |
Update host draft status |
published |
Refresh event/chart state and show release result |
close |
Navigate away or collapse editor |
error |
Show safe recovery UI; do not expose raw tokens |
Do not build business logic from the legacy resize message.
Session replacement
The SDK can proactively relaunch when onRequestRelaunch exists. It uses the
session expiry received from the iframe and replaces the iframe with the new
fragment URL. A slept device that wakes after expiry gets one automatic recovery
attempt before the error card appears.
Call destroy() when the host unmounts the editor.
Publication behavior
Publishing updates the chart. Existing events are separately protected: pristine events may auto-refresh; events with inventory state can require an explicit map update, and an update fails if booked or held labels would vanish. Surface this result to the organizer.
Verification
- The secret key is never present in browser code or network responses.
- Workspace and chart ownership are checked before minting.
- Origin matching is exact in production.
- Authority matches the host user’s role.
- Safe mode and feature policy match the editing job.
- Save, publish, close, expiry, relaunch, and revoke flows are tested.
- The container works at narrow widths and has a usable minimum height.
- Host code destroys the embed during teardown.
See embed sessions, publishing and versioning, and Designer MCP.