Without the SDK

The bare iframe and the postMessage protocol, if you want to wire the editor yourself.

The SDK is a thin wrapper: an iframe plus a few postMessage messages. If you would rather not add a dependency, the protocol below is everything the SDK does.

The iframe

<iframe
  src="https://pdfmerge.rsj.de/"
  title="PDF Merge"
  style="display: block; width: 100%; height: 640px; border: 0"
  allow="clipboard-read; clipboard-write; fullscreen"
  allowfullscreen
></iframe>

The handshake

The editor announces itself to its parent and waits for the configuration. Messages from the editor arrive from the editor's origin — check it, and check that event.source is your iframe's contentWindow.

Direction Message
editor → host {op: "init", partner: "pdfmerge", version}
host → editor {op: "initRsp", config} — the same config you would pass to the SDK

Driving the editor

Every request takes an id; the answer echoes it.

Direction Message Answer
host → editor {op: "addFiles", data: [File | dataURL | {name, data}]} {op: "addFilesRsp", count}
host → editor {op: "addPages", name, content, provenance?} {op: "addPagesRsp", ok}
host → editor {op: "pages"} {op: "pagesRsp", pages}
host → editor {op: "export", mode: "pdf" | "zip", part?, reference?} {op: "exportRsp", bytes, fileName, mimeType, pages}
editor → host {op: "action", action, where, reference, part} –
editor → host {op: "licenseRequest"} {op: "license", token}
editor → host {op: "licenseRsp", licensed, reason} –

content is a File, Blob, ArrayBuffer, Uint8Array, base64 string or data URL. exportRsp.bytes is an ArrayBuffer.

window.addEventListener('message', async (event) => {
  if (event.origin !== 'https://pdfmerge.rsj.de') return;
  if (event.source !== iframe.contentWindow) return;

  if (event.data?.op === 'init') {
    iframe.contentWindow.postMessage(
      { op: 'initRsp', partner: 'pdfmerge', config: { apiKey: jwt } },
      'https://pdfmerge.rsj.de',
    );
  }

  if (event.data?.op === 'licenseRequest') {
    iframe.contentWindow.postMessage(
      { op: 'license', token: jwt },
      'https://pdfmerge.rsj.de',
    );
  }
});

When to use the SDK instead

The SDK adds the origin checks, the id plumbing, promise-based methods, the React component and TypeScript types — about 4 kB. Use it unless you have a reason not to.