Controlling the Embed
Dynamically update template content, switch templates, and navigate pages via postMessage
Control the embed from your parent page using postMessage. You can switch templates, switch pages, and update layer content (text, images) without reloading the iframe.
| Event | Description |
|---|---|
| Setting Layer Modifications | Update text, image, and other layer values dynamically |
| Switching Templates | Switch to a different template within the embed |
| Switching Pages | Navigate to a specific page by index or ID |
| Switch Template + Set Modifications | Load a template with pre-filled values in one call |
| Controlling Custom Buttons | Change labels or show/hide custom buttons at runtime |
Setting Layer Modifications#
Update text and image layers dynamically:
const iframe = document.querySelector("iframe");
iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
modifications: {
text: "Hello World",
image: "https://example.com/photo.jpg",
},
},
"*",
);The modifications object uses layer parameter names as keys. These match the parameter names you've defined in your template.
Switching Templates#
Switch to a different template within the same embed:
iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
templateId: "481",
},
"*",
);Switching Pages#
For multi-page templates, switch to a specific page by index (1-based) or page ID:
// By page index (1-based)
iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
pageIndex: 1,
},
"*",
);
// By page ID
iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
pageId: "abc-123-uuid",
},
"*",
);You can combine page switching with modifications to switch to a page and update its content:
iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
pageIndex: 2,
modifications: {
headline: "Updated Slide 2",
},
},
"*",
);If both pageIndex and pageId are provided, pageId takes priority.
Switch Template + Set Modifications#
Combine both to load a specific template with pre-filled values:
iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
templateId: "481",
modifications: {
title: "My Custom Title",
subtitle: "Product description here",
image: "https://example.com/product.jpg",
},
},
"*",
);The embed will:
- Switch to the specified template
- Wait for it to load
- Apply the layer modifications
Controlling Custom Buttons#
Change the label or toggle visibility of custom buttons at runtime. Use the button ID shown in your embed settings (click to copy).
iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
customButtons: {
"custom-btn-1716384000000": { label: "Save to CRM", visible: false },
"custom-btn-1716384060000": { visible: true, label: "Export" },
},
},
"*",
);Each key is a button ID. Only the fields you include are overridden — omitted fields keep their configured defaults.
| Field | Type | Description |
|---|---|---|
label | string | Override the button's display text |
visible | boolean | Show (true) or hide (false) the button |
Overrides are session-scoped — they persist for the lifetime of the iframe and reset when the embed is reloaded.
You can combine customButtons with other control commands (modifications, template switching, etc.) in a single message.
Requirements: Custom buttons must be enabled on your plan and configured in your embed settings.
URL Parameters vs postMessage#
You can also set initial values via URL parameters:
<iframe
src="https://orshot.com/embeds/abc?templateId=481&title=Hello&image=https://..."
title="Orshot Embed"
allow="clipboard-write"
></iframe>| Method | Use Case |
|---|---|
| URL params | Initial load with pre-filled values |
| postMessage | Dynamic updates without reload |
Complete Example#
class EmbedController {
constructor(iframe) {
this.iframe = iframe;
}
// Update layer values
setModifications(modifications) {
this.iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
modifications,
},
"*",
);
}
// Switch to a different template
switchTemplate(templateId) {
this.iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
templateId,
},
"*",
);
}
// Switch template and set values
loadTemplate(templateId, modifications) {
this.iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
templateId,
modifications,
},
"*",
);
}
// Switch to a page by index (1-based)
switchPage(pageIndex) {
this.iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
pageIndex,
},
"*",
);
}
// Switch to a page by ID
switchPageById(pageId) {
this.iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
pageId,
},
"*",
);
}
// Update custom button labels or visibility
updateCustomButtons(overrides) {
this.iframe.contentWindow.postMessage(
{
type: "orshot:embed:control",
customButtons: overrides,
},
"*",
);
}
}
// Usage
const controller = new EmbedController(document.querySelector("iframe"));
// Update current template
controller.setModifications({
headline: "New Headline",
background: "https://example.com/bg.jpg",
});
// Switch to template 481 with custom values
controller.loadTemplate("481", {
title: "Product Launch",
price: "$99",
image: "https://example.com/product.jpg",
});
// Switch to page 2
controller.switchPage(2);
// Hide a button and relabel another
controller.updateCustomButtons({
"custom-btn-1716384000000": { visible: false },
"custom-btn-1716384060000": { label: "Send to CRM" },
});React Example#
import { useRef, useCallback } from "react";
function useEmbedController() {
const iframeRef = useRef(null);
const setModifications = useCallback((modifications) => {
iframeRef.current?.contentWindow?.postMessage(
{
type: "orshot:embed:control",
modifications,
},
"*",
);
}, []);
const loadTemplate = useCallback((templateId, modifications = {}) => {
iframeRef.current?.contentWindow?.postMessage(
{
type: "orshot:embed:control",
templateId,
modifications,
},
"*",
);
}, []);
const switchPage = useCallback((pageIndex) => {
iframeRef.current?.contentWindow?.postMessage(
{
type: "orshot:embed:control",
pageIndex, // 1-based
},
"*",
);
}, []);
const updateCustomButtons = useCallback((overrides) => {
iframeRef.current?.contentWindow?.postMessage(
{
type: "orshot:embed:control",
customButtons: overrides,
},
"*",
);
}, []);
return { iframeRef, setModifications, loadTemplate, switchPage, updateCustomButtons };
}
// Usage
function Editor() {
const { iframeRef, setModifications, loadTemplate, switchPage, updateCustomButtons } =
useEmbedController();
return (
<div>
<iframe
ref={iframeRef}
src="https://orshot.com/embeds/abc123?templateId=481"
title="Orshot Embed"
allow="clipboard-write"
/>
<button onClick={() => setModifications({ title: "Updated!" })}>
Update Title
</button>
<button onClick={() => loadTemplate("500", { title: "New Template" })}>
Switch Template
</button>
<button onClick={() => switchPage(2)}>Go to Page 2</button>
<button onClick={() => updateCustomButtons({
"custom-btn-1716384000000": { visible: false }
})}>
Hide Button
</button>
</div>
);
}Requirements#
- Enable Events must be turned on in your embed settings
- Embed control via postMessage is available only on supported plans
- Your domain must be in the embed's allowed domains list
- Layer parameter names in
modificationsmust match your template's defined parameters templateIdmust reference a template that exists in the embed's workspace
Ready to automate?
Start rendering images, PDFs and videos from your templates in under 2 minutes. Free plan, no credit card.
Get your API key- Image, PDF and video generation via API
- Visual editor with AI and smart layouts
- Zapier, Make, MCP and 50+ integrations
- White-label embed for your own app
- 60 free renders — no credit card required