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.

EventDescription
Setting Layer ModificationsUpdate text, image, and other layer values dynamically
Switching TemplatesSwitch to a different template within the embed
Switching PagesNavigate to a specific page by index or ID
Switch Template + Set ModificationsLoad a template with pre-filled values in one call
Controlling Custom ButtonsChange 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:

  1. Switch to the specified template
  2. Wait for it to load
  3. 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.

FieldTypeDescription
labelstringOverride the button's display text
visiblebooleanShow (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>
MethodUse Case
URL paramsInitial load with pre-filled values
postMessageDynamic 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 modifications must match your template's defined parameters
  • templateId must 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