The embed communicates with your parent page through postMessage events. You can listen for events when users save templates or download images, and request template content in any format.
| Event | Description |
|---|---|
orshot:template:create | Fired when a new template is created |
orshot:template:update | Fired when an existing template is saved |
orshot:download:png | Fired when downloaded as PNG |
orshot:download:pdf | Fired when downloaded as PDF |
orshot:download:html | Fired when downloaded as HTML |
orshot:template:content | Response with requested template content |
orshot:error | Error response for failed requests |
Set up a message listener to receive events from the embed:
window.addEventListener("message", (event) => {
// Verify the origin
if (!event.origin.includes("orshot.com")) return;
const { type, data, timestamp } = event.data;
switch (type) {
case "orshot:template:create":
console.log("Template created:", data);
break;
case "orshot:template:update":
console.log("Template updated:", data);
break;
case "orshot:download:png":
console.log("PNG downloaded:", data);
break;
case "orshot:download:pdf":
console.log("PDF downloaded:", data);
break;
case "orshot:download:html":
console.log("HTML downloaded:", data);
break;
case "orshot:template:content":
console.log("Template content received:", data);
break;
case "orshot:error":
console.error("Embed error:", event.data.error);
break;
}
});When a user creates or updates a template:
{
type: "orshot:template:create", // or "orshot:template:update"
timestamp: "2024-01-15T10:30:00.000Z",
data: {
id: 123,
name: "My Design",
workspaceId: 50
}
}When a user downloads from the embed:
// Single page download
{
type: "orshot:download:png",
timestamp: "2024-01-15T10:30:00.000Z",
data: {
templateId: 123,
templateName: "My Design",
pageIndex: 0,
scale: 2,
content: "data:image/png;base64,..." // base64 data URL
}
}
// Multi-page download
{
type: "orshot:download:png",
timestamp: "2024-01-15T10:30:00.000Z",
data: {
action: "zip", // "zip" for PNG/HTML, "multipage" for PDF
templateId: 123,
templateName: "My Design",
pageCount: 3,
scale: 2
}
}
// Copy to clipboard
{
type: "orshot:download:png",
timestamp: "2024-01-15T10:30:00.000Z",
data: {
action: "clipboard",
templateId: 123,
templateName: "My Design",
pageIndex: 0,
scale: 2,
content: "data:image/png;base64,..."
}
}Formats and their MIME types:
| Format | MIME Type |
|---|---|
| png | image/png |
| application/pdf | |
| html | text/html |
You can request the current template content from your parent page. Send a message to the embed iframe and receive the content in your preferred format.
{
type: "orshot:request:template",
requestId: "unique-request-id",
format: "png" // png, pdf, or html
}const iframe = document.querySelector("iframe");
const requestId = `req-${Date.now()}`;
// Send request to embed
iframe.contentWindow.postMessage(
{
type: "orshot:request:template",
requestId: requestId,
format: "png", // png, pdf, or html
},
"https://orshot.com" // Target origin - use your embed URL origin
);window.addEventListener("message", (event) => {
if (!event.origin.includes("orshot.com")) return;
if (event.data.type === "orshot:template:content") {
const { requestId, data } = event.data;
// data contains:
// - content: base64 data URL or HTML string
// - format: requested format
// - mimeType: content MIME type
// - templateId: template ID
// - templateName: template name
console.log("Received content:", data.format);
// Example: Create download from content
if (data.format === "png") {
const link = document.createElement("a");
link.href = data.content;
link.download = `${data.templateName}.png`;
link.click();
}
}
if (event.data.type === "orshot:error") {
console.error("Request failed:", event.data.error);
}
});Here's a full example that requests template content and handles the response:
class OrshotEmbedManager {
constructor(iframeSelector) {
this.iframe = document.querySelector(iframeSelector);
this.pendingRequests = new Map();
this.setupListener();
}
setupListener() {
window.addEventListener("message", (event) => {
if (!event.origin.includes("orshot.com")) return;
const { type, requestId, data, error } = event.data;
// Handle content response
if (type === "orshot:template:content" && requestId) {
const resolver = this.pendingRequests.get(requestId);
if (resolver) {
resolver.resolve(data);
this.pendingRequests.delete(requestId);
}
}
// Handle error response
if (type === "orshot:error" && requestId) {
const resolver = this.pendingRequests.get(requestId);
if (resolver) {
resolver.reject(new Error(error));
this.pendingRequests.delete(requestId);
}
}
// Handle save events
if (type === "orshot:template:create") {
this.onTemplateCreate?.(data);
}
if (type === "orshot:template:update") {
this.onTemplateUpdate?.(data);
}
// Handle download events
if (type.startsWith("orshot:download:")) {
this.onDownload?.(data);
}
});
}
requestContent(format = "png") {
return new Promise((resolve, reject) => {
const requestId = `req-${Date.now()}`;
this.pendingRequests.set(requestId, { resolve, reject });
this.iframe.contentWindow.postMessage(
{
type: "orshot:request:template",
requestId,
format,
},
"https://orshot.com" // Target origin - use your embed URL origin
);
// Timeout after 30 seconds
setTimeout(() => {
if (this.pendingRequests.has(requestId)) {
this.pendingRequests.delete(requestId);
reject(new Error("Request timed out"));
}
}, 30000);
});
}
}
// Usage
const manager = new OrshotEmbedManager("iframe");
// Listen to events
manager.onTemplateCreate = (data) => console.log("Created:", data);
manager.onTemplateUpdate = (data) => console.log("Updated:", data);
manager.onDownload = (data) => console.log("Downloaded:", data);
// Request content
const pngContent = await manager.requestContent("png");
const htmlContent = await manager.requestContent("html");
const pdfContent = await manager.requestContent("pdf");import { useEffect, useRef, useCallback } from "react";
function useOrshotEmbed() {
const embedRef = useRef(null);
const pendingRequests = useRef(new Map());
useEffect(() => {
const handleMessage = (event) => {
if (!event.origin.includes("orshot.com")) return;
const { type, requestId, data, error } = event.data;
if (type === "orshot:template:content" && requestId) {
const resolver = pendingRequests.current.get(requestId);
if (resolver) {
resolver.resolve(data);
pendingRequests.current.delete(requestId);
}
}
if (type === "orshot:error" && requestId) {
const resolver = pendingRequests.current.get(requestId);
if (resolver) {
resolver.reject(new Error(error));
pendingRequests.current.delete(requestId);
}
}
};
window.addEventListener("message", handleMessage);
return () => window.removeEventListener("message", handleMessage);
}, []);
const requestContent = useCallback((format = "png") => {
return new Promise((resolve, reject) => {
const requestId = `req-${Date.now()}`;
pendingRequests.current.set(requestId, { resolve, reject });
embedRef.current?.contentWindow?.postMessage(
{ type: "orshot:request:template", requestId, format },
"https://orshot.com" // Target origin - use your embed URL origin
);
setTimeout(() => {
if (pendingRequests.current.has(requestId)) {
pendingRequests.current.delete(requestId);
reject(new Error("Request timed out"));
}
}, 30000);
});
}, []);
return { embedRef, requestContent };
}
// Usage
function DesignEditor() {
const { embedRef, requestContent } = useOrshotEmbed();
const handleExport = async (format) => {
try {
const content = await requestContent(format);
console.log("Got content:", content);
} catch (error) {
console.error("Export failed:", error);
}
};
return (
<div>
<iframe ref={embedRef} src="https://orshot.com/embeds/abc123" />
<button onClick={() => handleExport("png")}>Export PNG</button>
<button onClick={() => handleExport("pdf")}>Export PDF</button>
<button onClick={() => handleExport("html")}>Export HTML</button>
</div>
);
}Events must be enabled in your embed settings. Go to your workspace embed configuration and toggle Enable Events to start receiving events.
When disabled, the embed won't send any postMessage events to your parent page.
A common use case is to automatically fetch the template HTML whenever a user creates or updates a template. This allows you to sync the design content with your backend or display it elsewhere.
const iframe = document.querySelector("iframe");
window.addEventListener("message", async (event) => {
if (!event.origin.includes("orshot.com")) return;
const { type, data } = event.data;
// Listen for template create or update events
if (type === "orshot:template:create" || type === "orshot:template:update") {
console.log(
`Template ${type === "orshot:template:create" ? "created" : "updated"}:`,
data
);
// Request the HTML content
const requestId = `html-${Date.now()}`;
iframe.contentWindow.postMessage(
{
type: "orshot:request:template",
requestId: requestId,
format: "html",
},
"https://orshot.com" // Target origin - use your embed URL origin
);
}
// Handle the HTML content response
if (type === "orshot:template:content") {
const { content, format, templateId, templateName } = event.data.data;
if (format === "html") {
console.log("Received HTML for template:", templateName);
// Example: Send to your backend
await fetch("/api/templates/sync", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
templateId,
templateName,
html: content,
}),
});
// Or store locally
localStorage.setItem(`template-${templateId}-html`, content);
// Or render in a preview container
document.getElementById("preview").innerHTML = content;
}
}
});import { useEffect, useRef, useState } from "react";
function DesignEditorWithAutoSync() {
const embedRef = useRef(null);
const [lastSavedHtml, setLastSavedHtml] = useState(null);
const [templateInfo, setTemplateInfo] = useState(null);
useEffect(() => {
const handleMessage = (event) => {
if (!event.origin.includes("orshot.com")) return;
const { type, data, requestId } = event.data;
// Auto-request HTML on create/update
if (
type === "orshot:template:create" ||
type === "orshot:template:update"
) {
setTemplateInfo(data);
// Request HTML content
embedRef.current?.contentWindow?.postMessage(
{
type: "orshot:request:template",
requestId: `auto-html-${Date.now()}`,
format: "html",
},
"https://orshot.com" // Target origin - use your embed URL origin
);
}
// Handle HTML response
if (
type === "orshot:template:content" &&
event.data.data.format === "html"
) {
setLastSavedHtml(event.data.data.content);
// Sync with your backend
syncWithBackend(event.data.data);
}
};
window.addEventListener("message", handleMessage);
return () => window.removeEventListener("message", handleMessage);
}, []);
const syncWithBackend = async (data) => {
try {
await fetch("/api/templates/sync", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
templateId: data.templateId,
html: data.content,
}),
});
} catch (error) {
console.error("Sync failed:", error);
}
};
return (
<div>
<iframe ref={embedRef} src="https://orshot.com/embeds/abc123" />
{templateInfo && (
<p>
Last saved: {templateInfo.name} (ID: {templateInfo.id})
</p>
)}
</div>
);
}