New to Preview in the Apps SDK: duplicatePage and addPage.insertAt

We’re excited to announce two new page-management capabilities in the Apps SDK preview: duplicatePage and insertAt support for addPage.

Together, these updates give apps more control over both how pages are created and where they appear in a design.

What’s new

With this preview release:

  • duplicatePage lets apps duplicate an existing page, making it easier to build workflows based on an established page layout or content.
  • addPage now supports insertAt, so apps can choose where a new page is inserted instead of always adding it after the current page.

Both APIs let you place pages at the beginning or end of the design, or before or after a specific page using its page ID. For placement closer to where you’re working, addPage supports inserting before or after the current page, while duplicatePage supports inserting before or after the source page being duplicated.

Why it matters

These APIs make page-aware workflows more flexible. Apps can now preserve a known layout by duplicating a page, or insert generated content exactly where it belongs in a design.

For example, an app could add a cover page at the start of a presentation, create a summary page immediately before the current page, or duplicate a reusable page before populating it with new content.

How to use it

Add a page after a target page

Use insertAt with addPage to insert a new page before a specific page using its ID. This example uses the current page as the target:

import { addPage, getCurrentPageMetadata } from "@canva/design";

const targetPage = await getCurrentPageMetadata();

if (targetPage.type !== "absolute" || targetPage.id == null) {
  throw new Error("Target page does not have an ID");
}

await addPage({
  title: "Summary",
  insertAt: {
    mode: "before_target",
    targetPageId: targetPage.id,
  },
});

Duplicate a page at the end of the design

Use duplicatePage with after_last_page to copy an existing page and place the duplicate at the end of the design:

import { duplicatePage, getCurrentPageMetadata } from "@canva/design";

const sourcePage = await getCurrentPageMetadata();

if (sourcePage.type !== "absolute" || sourcePage.id == null) {
  throw new Error("Source page does not have an ID");
}

await duplicatePage({
  sourcePageId: sourcePage.id,
  mode: "after_last_page",
});

As with all preview APIs, these capabilities are unstable and may change without warning. They can’t be used in public apps until they become stable.

3 Likes