# Events

> Listen to embed events and request template content programmatically

- **URL**: https://orshot.com/docs/orshot-embed/events

---

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 Types

| Event                     | Direction      | Description                              |
| ------------------------- | -------------- | ---------------------------------------- |
| `orshot:template:create`  | Embed → Parent | Fired when a new template is created     |
| `orshot:template:update`  | Embed → Parent | Fired when an existing template is saved |
| `orshot:download:png`     | Embed → Parent | Fired when downloaded as PNG             |
| `orshot:download:jpeg`    | Embed → Parent | Fired when downloaded as JPEG            |
| `orshot:download:webp`    | Embed → Parent | Fired when downloaded as WEBP            |
| `orshot:download:pdf`     | Embed → Parent | Fired when downloaded as PDF             |
| `orshot:download:html`    | Embed → Parent | Fired when downloaded as HTML            |
| `orshot:template:content` | Embed → Parent | Response with requested template content |
| `orshot:asset:request`    | Embed → Parent | User wants to pick a custom asset        |
| `orshot:asset:response`   | Parent → Embed | Send selected asset back to embed        |
| `orshot:asset:cancel`     | Parent → Embed | Cancel a pending asset request           |
| `orshot:asset:error`      | Embed → Parent | Error when asset picker plan requirement not met |
| `orshot:error`            | Embed → Parent | Error response for failed requests       |

## Listening to Events

Set up a message listener to receive events from the embed:```javascript
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:jpeg":
      console.log("JPEG downloaded:", data);
      break;

    case "orshot:download:webp":
      console.log("WEBP 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;
  }
});
```## Event Payloads

### Template Events

When a user creates or updates a template:```javascript
{
  type: "orshot:template:create", // or "orshot:template:update"
  timestamp: "2024-01-15T10:30:00.000Z",
  data: {
    id: 123,
    name: "My Design",
    workspaceId: 50
  }
}
```### Download Events

When a user downloads from the embed:```javascript
// 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       |
| pdf    | application/pdf |
| html   | text/html       |

## Requesting Template Content

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.

### Request Message Format```javascript
{
  type: "orshot:request:template",
  requestId: "unique-request-id",
  format: "png" // png, pdf, or html
}
```### Sending a Request```javascript
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
);
```### Handling the Response```javascript
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);
  }
});
```## Complete Example

Here's a full example that requests template content and handles the response:```javascript
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");
```## React Example```jsx
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" title="Orshot Embed" allow="clipboard-write" />
      <button onClick={() => handleExport("png")}>Export PNG</button>
      <button onClick={() => handleExport("pdf")}>Export PDF</button>
      <button onClick={() => handleExport("html")}>Export HTML</button>
    </div>
  );
}
```## Enable Events

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.

## Get Template HTML on Create/Update

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.```javascript
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;
    }
  }
});
```### React Example```jsx
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" title="Orshot Embed" allow="clipboard-write" />
      {templateInfo && (
        <p>
          Last saved: {templateInfo.name} (ID: {templateInfo.id})
        </p>
      )}
    </div>
  );
}
```