Message API/docs/components/pdf/page-insert

Page Insert

Insert pages from another PDF into the current PDF with page-insert.

Overview

The `page-insert` action imports pages from another PDF file into the current PDF. The parent provides a browser `File` object and identifies which source pages should be inserted.

The target location is defined by `pageRange` in the current PDF, while `selectedPages` identifies the pages to import from the source file.

  • Required fields: `pageRange`, `file`, and `selectedPages`.
  • The `file` value must be the source PDF chosen in the parent application.
  • Use this action when you are adding pages without replacing existing ones.

Example

Pick the source PDF from a file input, then send the insertion request with the selected source pages.

const file = input.files[0];

viewerWindow.postMessage({
  type: 'pageManipulation',
  payload: {
    requestId: 'insert-1',
    action: 'page-insert',
    pageRange: [[2]],
    file,
    selectedPages: [[0, 1]]
  }
}, '*');
Example

Complete HTML Example

Use this full standalone HTML document when you want a minimal host page for inserting pages from another PDF.

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>PDF Page Insert Demo</title>
  <style>
    body {
      margin: 0;
      font-family: Arial, sans-serif;
      background: #0b1220;
      color: #e5e7eb;
    }
    .app {
      display: grid;
      grid-template-columns: 320px 1fr;
      gap: 12px;
      min-height: 100vh;
      padding: 12px;
    }
    .panel {
      border: 1px solid #2f3b4f;
      border-radius: 12px;
      background: #111827;
      padding: 12px;
      display: grid;
      gap: 10px;
      align-content: start;
    }
    .stack {
      display: grid;
      gap: 8px;
    }
    .row {
      display: flex;
      gap: 8px;
      flex-wrap: wrap;
    }
    input, button, select {
      width: 100%;
      border: 1px solid #2f3b4f;
      border-radius: 8px;
      background: #0f172a;
      color: #e5e7eb;
      padding: 8px 10px;
      font: inherit;
      box-sizing: border-box;
    }
    button {
      width: auto;
      cursor: pointer;
    }
    .pages {
      display: grid;
      gap: 8px;
      max-height: 60vh;
      overflow: auto;
    }
    .page {
      border: 1px solid #2f3b4f;
      border-radius: 10px;
      background: #0d1728;
      padding: 8px;
      display: grid;
      gap: 8px;
    }
    .page.active {
      border-color: #22d3ee;
    }
    iframe {
      width: 100%;
      height: calc(100vh - 24px);
      border: 1px solid #2f3b4f;
      border-radius: 12px;
      background: #04101c;
    }
    img {
      max-width: 100%;
      height: auto;
      display: block;
      background: #fff;
      border-radius: 8px;
    }
    .meta {
      font-size: 12px;
      color: #9ca3af;
    }
  </style>
</head>
<body>
  <div class="app">
    <div class="panel">
      <div class="stack">
      <input id="viewerUrl" value="http://localhost:5173" />
      <input id="fileUrl" placeholder="Public PDF URL" />
      <div class="row">
        <button id="loadViewerBtn">Load Viewer</button>
        <button id="loadPdfBtn">Load PDF</button>
      </div>
      <input id="targetRangeInput" value="[[0]]" />
      <input id="selectedPagesInput" value="[[0]]" />
      <input id="sourceFileInput" type="file" accept="application/pdf" />
      <button id="insertBtn">Insert Pages</button>
      <div id="pages" class="pages"></div>
    </div>
    </div>
    <iframe id="viewerFrame" title="PDF Page Insert Demo Viewer"></iframe>
  </div>
  <script>
const viewerFrame = document.getElementById('viewerFrame');
const viewerUrlInput = document.getElementById('viewerUrl');
const fileUrlInput = document.getElementById('fileUrl');
const pagesEl = document.getElementById('pages');
let latestPageList = null;

function post(type, payload) {
  viewerFrame.contentWindow.postMessage({ type, payload }, '*');
}

function loadViewer() {
  viewerFrame.src = viewerUrlInput.value.trim();
}

function loadPdf() {
  post('view', {
    fileUrl: fileUrlInput.value.trim(),
    displayName: 'Demo User',
    username: 'demo.user',
    email: 'demo@example.com'
  });
}

window.addEventListener('message', (event) => {
  if (event.source !== viewerFrame.contentWindow) return;
  const data = event.data;
  if (!data || typeof data !== 'object') return;
  if (data.type === 'pageList') {
    latestPageList = data.payload;
    renderPages(data.payload.pages);
  }
  onViewerMessage(data);
});

function renderPages(pages) {
  if (!pagesEl) return;
  pagesEl.innerHTML = '';
  pages.forEach((page) => {
    const item = document.createElement('div');
    item.className = page.isSelected ? 'page active' : 'page';
    const actions = pageActions(page);
    item.innerHTML = [
      page.thumbnailDataUrl
        ? '<img src="' + page.thumbnailDataUrl + '" width="' + (page.thumbnailWidth || 120) + '" height="' + (page.thumbnailHeight || 160) + '" />'
        : '<div class="meta">No thumbnail data</div>',
      '<div><strong>' + (page.label || ('Page ' + (page.index + 1))) + '</strong></div>',
      '<div class="meta">' + (page.title || 'Default') + '</div>',
      actions
    ].join('');
    wirePageActions(item, page);
    pagesEl.appendChild(item);
  });
}

document.getElementById('loadViewerBtn').addEventListener('click', loadViewer);
document.getElementById('loadPdfBtn').addEventListener('click', loadPdf);

let sourceFile = null;
document.getElementById('sourceFileInput').addEventListener('change', (event) => {
  sourceFile = event.target.files && event.target.files[0] ? event.target.files[0] : null;
});
document.getElementById('insertBtn').addEventListener('click', () => {
  const pageRange = parseRangeInput(document.getElementById('targetRangeInput').value);
  const selectedPages = parseRangeInput(document.getElementById('selectedPagesInput').value);
  post('pageManipulation', { requestId: 'insert-1', action: 'page-insert', pageRange, file: sourceFile, selectedPages });
});
function pageActions() { return ''; }
function wirePageActions() {}
function onViewerMessage(data) {
  if (data.type === 'pageManipulationResult') console.log(data.payload);
}
  </script>
</body>
</html>
Complete HTML Example

Live Preview

Open the focused demo to test page insertion from another PDF file.

PDF Page Insert Demo

Focused live demo for page-insert.

Preview opens in a large modal for zoom-friendly review.