> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.templated.io/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Embedded Editor Events (postMessage)

The Templated embedded editor talks to your page with browser messages (`window.postMessage`). Your page can:

- **Listen** to events from the editor, for example when a template loads, is saved or is downloaded.
- **Send** commands to the editor, for example save, download or change the zoom.

This works without a backend. For server-side notifications, use the webhook URL in your embed configuration (see "Webhook Integration"). The `create`, `save` and `download` actions are sent both to your webhook and to your page.

Docs: https://templated.io/docs/embed/webhooks/ and https://templated.io/docs/embed/preview-mode/

## Events the editor sends to your page

| Event | When | Main fields |
|---|---|---|
| `EDITOR_READY` | The editor started and can receive messages | none (no template ID) |
| `TEMPLATE_LOADED` | The template finished loading | `template.id`, `template.name`, `template.width`, `template.height` |
| action `create` | A new template or clone was created (for example with `clone=true`) | `templateId`, `metadata` |
| action `save` | The user saved | `templateId`, `metadata` |
| action `download` | A download finished | `templateId`, `renderId`, `renderUrl`, `metadata` |
| `TEMPLATE_SAVED_SUCCESS` | A save requested with the `SAVE` message finished | `templateId` |
| `TEMPLATE_DOWNLOADED_SUCCESS` | A download requested with the `DOWNLOAD` message finished | `templateId`, `renderId`, `renderUrl`, `format` |
| `TEMPLATE_DOWNLOAD_ERROR` | A requested download failed | `error` |
| `ZOOM_UPDATED` | Zoom changed with `SET_ZOOM` | `zoom` |
| `LAYER_SELECTED` | The user selected a layer | `data.name`, `data.type` |

Important: there are two message styles.

- Events with a `type` field (like `EDITOR_READY` and `TEMPLATE_LOADED`) arrive as JavaScript objects.
- The `create`, `save` and `download` actions arrive as a JSON **string** with an `action` field. Parse it with `JSON.parse`.

## Example listener

```js
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://app.templated.io') return;

  let msg = event.data;
  if (typeof msg === 'string') {
    try { msg = JSON.parse(msg); } catch (e) { return; }
  }

  // Events with "type"
  switch (msg.type) {
    case 'EDITOR_READY':
      console.log('Editor ready');
      break;
    case 'TEMPLATE_LOADED':
      console.log('Template ID (clone ID when clone=true):', msg.template.id);
      break;
    case 'TEMPLATE_DOWNLOADED_SUCCESS':
      console.log('Render URL:', msg.renderUrl);
      break;
  }

  // Actions (create / save / download)
  switch (msg.action) {
    case 'create':
      console.log('New template or clone:', msg.templateId, msg.metadata);
      break;
    case 'save':
      console.log('Saved:', msg.templateId);
      break;
    case 'download':
      console.log('Downloaded:', msg.renderId, msg.renderUrl);
      break;
  }
});
```

## Getting the template or clone ID

- Use `TEMPLATE_LOADED`: `msg.template.id` is the ID of the template that is open. With `clone=true` or `render=...`, this is the new clone ID.
- Or use the `create` and `save` actions: `msg.templateId`.
- `EDITOR_READY` does not include any ID. It only tells you the editor is ready for messages.

Add your own data (user ID, order ID) with the `metadata` URL parameter (base64-encoded JSON). It comes back in `create`, `save` and `download`.

## Commands your page can send to the editor

Get the iframe and send a message after `EDITOR_READY`:

```js
const iframe = document.getElementById('templated-editor');

// Save the template
iframe.contentWindow.postMessage({ type: 'SAVE' }, '*');

// Download using the format selected in the editor
iframe.contentWindow.postMessage({ type: 'DOWNLOAD' }, '*');

// Download with a specific format and pages
iframe.contentWindow.postMessage({
  type: 'DOWNLOAD',
  format: 'png',   // 'jpg', 'png', 'pdf' or 'mp4'
  pages: 'all'     // 'all' (default), page numbers like '1,3' or a range like '2-4' (first page = 1)
}, '*');

// Change the zoom (10 to 100, 50 = 100% scale)
iframe.contentWindow.postMessage({ type: 'SET_ZOOM', zoom: 60 }, '*');

// Change layer values without reloading
iframe.contentWindow.postMessage({
  type: 'UPDATE_LAYERS',
  data: { 'title': { text: 'New title' } }
}, '*');

// Open another template without reloading
iframe.contentWindow.postMessage({ type: 'LOAD_TEMPLATE', templateId: 'TEMPLATE_ID', clone: false }, '*');
```

Notes:

- `SAVE` works only when saving is allowed in your embed configuration.
- `DOWNLOAD` works only when download is allowed and uses credits from your account, like a download from the button. With your own buttons you can hide the editor's Save button with `&hide-save-button=true`.
- The full list of messages (add or remove layers, change permissions, show one page, get layers) is in the Preview Mode docs: https://templated.io/docs/embed/preview-mode/

## FAQ

Q: How do I know when the user saved?
A: Listen for the `save` action (frontend) or use the webhook. Both include `templateId`.

Q: How do I get the clone ID in my frontend?
A: Listen for `TEMPLATE_LOADED` and read `template.id`. With `clone=true` you also receive a `create` action with `templateId`.

Q: EDITOR_READY has no template ID. Is that a bug?
A: No. `EDITOR_READY` only means the editor is ready. The ID comes in `TEMPLATE_LOADED`.

Q: My listener gets the save event but `event.data.action` is undefined. Why?
A: The `create`, `save` and `download` actions are sent as a JSON string. Run `JSON.parse(event.data)` first.

Q: Can I trigger the download from my own button?
A: Yes. Send `{ type: 'DOWNLOAD', format: 'png' }` to the iframe. You receive `TEMPLATE_DOWNLOADED_SUCCESS` with the `renderUrl`.

Q: Can I change the zoom after the editor loads?
A: Yes. Send `{ type: 'SET_ZOOM', zoom: 60 }`.