Design Editing API
The Design Editing API enables apps to read and edit the "ingredients" of a design, such as pages and elements. This unlocks a range of powerful capabilities for programmatically creating and manipulating designs.
This page introduces the fundamentals of working with the API, along with some common use-cases, but the best way to understand the full scope of what's possible is to browse the API reference.
Our design guidelines help you create a high-quality app that easily passes app review.

Core concepts
The Design Editing API exposes a single openDesign
method:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {console.log(session);});
This method is packed with powerful capabilities and some subtle nuances, so before diving into using it, it's important to first understand a few key details about how it works.
Design contexts
The first argument of the openDesign
method specifies a design context:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {console.log(session);});
This determines what part of the design to read and edit. For the time being, apps can only read the current page of the design. In the future, other contexts will be supported.
Sessions
The second argument of the openDesign
method is a callback function that receives a session
object. The contents of this object partly depends on the design context.
When the design context is the current page, the session
object contains:
- a snapshot of the current page, including the elements it contains
- helper functions for performing complex operations (e.g., grouping elements)
- a
sync
method for syncing the snapshot with the live design
For example:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {console.log(session.page); // the snapshot of the designconsole.log(session.helpers); // the helper functionsconsole.log(session.sync); // the sync() method});
Syncing
While the callback is running, the live design may continue to change. For example, someone collaborating on the design may change it in some way. This means that the snapshot of the design and live design can fall out of sync.
To account for this, the callback receives a sync
method:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}// Get the initial count of elementsconst initialCount = session.page.elements.count();console.log(`Initial element count: ${initialCount}`);// The sync method updates the snapshot with the latest stateawait session.sync();// If someone else added elements, the count might be differentconst updatedCount = session.page.elements.count();console.log(`Updated element count: ${updatedCount}`);if (updatedCount !== initialCount) {console.log("The design was modified by another user!");}});
The sync
method does two things:
- Updates the live design with any edits that have been made to the snapshot.
- Updates the snapshot, so that the callback has access to the latest state of the design.
That second point is particularly important, as edits to the snapshot are not automatically reflected in the design. Apps must call the sync
method for the edits to be applied:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Create a text elementconst textElementState =session.helpers.elementStateBuilder.createTextElement({top: 100,left: 100,width: 200,text: {regions: [{text: "This text won't appear until we sync!",formatting: {fontSize: 20,color: "#ff0099",},},],},});// Add the element to the pagesession.page.elements.insertAfter(undefined, textElementState);// At this point, the element exists in the snapshot but *not* in the live designconsole.log("Element added to snapshot");// Call sync to apply the changes to the live designawait session.sync();console.log("Changes synced - element now visible in the design!");});
Any edits made to the snapshot that are not synced will be discarded when the callback is disposed.
Conflicts
It's possible for there to be conflicts between the snapshot and the live design. In these cases, Canva will attempt to resolve the conflict. If the conflict can't be resolved, the edit that occurs outside of the app will take precedence.
Lists
Throughout the Design Editing API, various things are exposed as lists, including:
- The elements on a page
- The elements in a group
- The paths of a shape
- The regions of text in a richtext range
These lists provide methods for operating on the lists (and the items within them), such as filter
, indexOf
, and forEach
. These methods are an essential part of reading and editing a design because they allow apps to make both sweeping changes (e.g., all shapes in a design) and targeted changes (e.g., only text elements with a certain string).
The available methods depend on the thing being operated on. For example, when reading a shape element, the shape's paths are read-only, so mutation methods aren't available.
The list methods are comparable to the native JavaScript methods, but are not identical. Be careful about making assumptions about their signatures and behavior.
Pages
Designs are made up of one or more pages.
Using the Design Editing API, apps can:
- Read the metadata of pages (e.g., whether or not the page is locked)
- Read and edit the page's ingredients (e.g., the background of a page)
Page types
All pages have an associated type:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {console.log(session.page.type); // => "absolute" or "unsupported"});
For the time being, apps can only interact with absolute pages. All other types of pages are unsupported. The most notable consequence of this is that the Design Editing API is not compatible with documents(opens in a new tab or window).
Absolute pages
Absolute pages are pages that have either:
- fixed dimensions (i.e., a width and a height)
- unbounded dimensions (i.e., are infinite)
An example of an absolute page with fixed dimensions is a presentation page. This is the most common type of page in Canva. The only example of a page that has unbounded dimensions is a whiteboard(opens in a new tab or window).
The following code sample demonstrates how to check if the current page has fixed or unbounded dimensions:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type === "absolute") {if (session.page.dimensions) {console.log("The current page has fixed dimensions.");} else {console.log("The current page has unbounded dimensions.");}}});
Unsupported pages
When a page is of an unsupported type, apps cannot read or edit it. Before attempting to interact with a page, always check if the page is unsupported:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type === "unsupported") {console.log("The current page is not supported.");return;}});
Locked pages
Pages can be locked.
When a page is locked, its metadata and ingredients are read-only. If an app attempts to read or edit a locked page, an error is thrown. Before attempting to edit a page, always check if the page is locked:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.locked) {console.log("The page is locked, so no edits are allowed.");return;}});
Backgrounds
Backgrounds are base layers that appear behind all other ingredients on a page. The appearance of a background is defined as a fill, which means they can contain colors, images, or videos.
The following code sample demonstrates how to check if a page has a background:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}if (!session.page.background) {console.log("The page doesn't have a background.");return;}console.log(session.page.background); // => Fill});
To learn more about fills, including how to set them, see Fills.
Elements
Elements are the visual objects that users can add to their designs, such as shapes, text, and groups. Apps can use the Design Editing API to create, read, update, and delete elements.
All elements share some common properties and behavior, which is what this section covers. To learn more about the unique characteristics of the supported element types, see Element types.
Locked elements
Like pages, elements can be locked. When an element is locked, its properties can be read but not modified. Be sure to check if an element is locked before attempting to modify it:
import { openDesign, type DesignEditing } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}const textElement = session.page.elements.toArray().find((element): element is DesignEditing.TextElement => element.type === "text");if (textElement.locked) {console.log("The element is locked and cannot be modified.");}});
Creating elements
To create an element, first initialize the state of the element with one of the following helper methods:
createEmbedElement
createRectElement
createShapeElement
createTextElement
For example:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Create a shape element (e.g., a circle)const shapeElementState =session.helpers.elementStateBuilder.createShapeElement({top: 100,left: 350,width: 100,height: 100,viewBox: {top: 0,left: 0,width: 100,height: 100,},paths: [{d: "M 50 0 A 50 50 0 1 1 50 100 A 50 50 0 1 1 50 0 Z",fill: {colorContainer: {type: "solid",color: "#0099ff",},},},],});});
Then add the element to the design with one of the available list methods, such as insertAfter
:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Create a shape element (e.g., a circle)const shapeElementState =session.helpers.elementStateBuilder.createShapeElement({top: 100,left: 350,width: 100,height: 100,viewBox: {top: 0,left: 0,width: 100,height: 100,},paths: [{d: "M 50 0 A 50 50 0 1 1 50 100 A 50 50 0 1 1 50 0 Z",fill: {colorContainer: {type: "solid",color: "#0099ff",},},},],});// Insert after the last elementsession.page.elements.insertAfter(undefined, shapeElementState);// Apply changesawait session.sync();});
Be sure to call the sync
method for the change to be reflected in the user's design.
Reading elements
To read the elements on the page, use one of the available list methods, such as forEach
or filter
:
import { openDesign, type DesignEditing } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}// Iterate through all elementssession.page.elements.forEach((element, index) => {console.log(`Element ${index}: ${element.type}`);// Read element propertiesconsole.log(`Position: ${element.top}, ${element.left}`);console.log(`Dimensions: ${element.width}x${element.height}`);console.log(`Rotation: ${element.rotation}`);console.log(`Locked: ${element.locked}`);});// Filter specific element typesconst textElements = session.page.elements.filter((element): element is DesignEditing.TextElement => element.type === "text");console.log(`Found ${textElements.length} text elements`);textElements.forEach((textElement) => {const plaintext = textElement.text.readPlaintext();console.log(`Text content: ${plaintext}`);});// Find shapes with specific propertiesconst blueShapes = session.page.elements.filter((element) => {if (element.type !== "shape") return false;return element.paths.toArray().some((path) => {const colorFill = path.fill.colorContainer?.ref;return colorFill?.type === "solid" && colorFill.color === "#0099ff";});});console.log(`Found ${blueShapes.length} blue shapes`);});
Updating elements
To update elements, mutate their properties and sync the changes:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}session.page.elements.forEach((element) => {// Skip locked elementsif (element.locked) {return;}// Update positionelement.top += 50;element.left += 50;// Update rotationelement.rotation += 15;// Update transparencyelement.transparency = 0.8;// Update element-specific propertiesswitch (element.type) {case "rect":// Update rect fill colorelement.fill.colorContainer.set({type: "solid",color: "#ff6600",});break;case "text":// Update text content and formattingelement.text.replaceText({ index: 0, length: element.text.readPlaintext().length },"Updated text content",{color: "#0066ff",fontSize: 20,fontWeight: "bold",});break;case "shape":// Update shape path colorselement.paths.forEach((path) => {if (path.fill.colorContainer?.ref?.type !== "solid") {return;}path.fill.colorContainer.set({type: "solid",color: "#00ff66",});});break;case "embed":// Embeds have limited update capabilitiesconsole.log(`Embed URL: ${element.url}`);break;}});// Apply all changesawait session.sync();});
Be aware that some properties are read-only.
Deleting elements
To delete elements, call the delete
method on an element and sync the changes:
import { openDesign, type DesignEditing } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Delete a specific element by referenceconst elements = session.page.elements.toArray();if (elements.length > 0) {// Delete the first elementsession.page.elements.delete(elements[0]);}// Delete all text elementsconst textElements = session.page.elements.filter((element): element is DesignEditing.TextElement => element.type === "text");textElements.forEach((textElement) => {session.page.elements.delete(textElement);});// Delete elements based on a conditionsession.page.elements.forEach((element) => {// Delete small elements (less than 50x50 pixels)if (element.width < 50 && element.height < 50) {session.page.elements.delete(element);return;}// Delete transparent elementsif (element.transparency && element.transparency > 0.9) {session.page.elements.delete(element);return;}});// Delete all elements except groupsconst nonGroupElements = session.page.elements.filter((element) => element.type !== "group");nonGroupElements.forEach((element) => {session.page.elements.delete(element);});// Apply deletionsawait session.sync();});
Element types
Canva supports a wide variety of elements, a subset of which apps can interact with via the Design Editing API.
The supported element types include:
- Embeds
- Groups
- Rects
- Shapes
- Text
Be aware that, unlike other parts of the SDK:
- The Design Editing API doesn't have a concept of image or video elements. Instead, images are videos are handled as rects with fills. This is more aligned with how Canva works under the hood.
- Text elements are only available as richtext ranges, rather than richtext and plaintext. However, richtext ranges can be converted into plaintext, so it's only one extra step.
- Table elements are not currently supported.
This section covers the unique aspects of the supported element types.
Embed elements
Embed elements allow you to include rich media content from external sources, such as YouTube videos, Vimeo content, or other embeddable media supported by Iframely(opens in a new tab or window).
Creating embed elements
To create an embed element, provide a URL to embeddable content using the createEmbedElement
helper method:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}const embedElementState =session.helpers.elementStateBuilder.createEmbedElement({top: 50,left: 50,width: 560,height: 315,rotation: 0,transparency: 0,url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",});session.page.elements.insertAfter(undefined, embedElementState);await session.sync();});
Group elements
Group elements contain other elements and allow them to be moved, rotated, and scaled as a single unit. Groups are essential for organizing complex designs.
Grouping elements
To create a group, first add the elements you want to group to the page, then use the group
helper method:
import { openDesign, type DesignEditing } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Create elements to groupconst rectElementState =session.helpers.elementStateBuilder.createRectElement({top: 0,left: 0,width: 100,height: 100,fill: {colorContainer: {type: "solid",color: "#3498db",},},});const textElementState =session.helpers.elementStateBuilder.createTextElement({top: 35,left: 25,width: 50,text: {regions: [{text: "Box",formatting: {fontSize: 16,color: "#ffffff",textAlign: "center",},},],},});// Add elements to snapshotconst addedRect = session.page.elements.insertAfter(undefined,rectElementState);const addedText = session.page.elements.insertAfter(addedRect,textElementState);// Group the elementsconst groupElement = await session.helpers.group({elements: [addedRect, addedText],});await session.sync();});
Ungrouping elements
To ungroup elements, use the ungroup
helper method on an existing group:
import { openDesign, type DesignEditing } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Find first unlocked groupconst [groupElement] = session.page.elements.filter((element): element is DesignEditing.GroupElement =>element.type === "group" && !element.locked);if (!groupElement) {console.log("Group element not found in design.");return;}const ungroupedElements = await session.helpers.ungroup({element: groupElement,});console.log(`Ungrouped ${ungroupedElements.length} elements`);await session.sync();});
Iterating through group contents
Groups provide a contents
list that allows you to access and iterate through the child elements:
import { openDesign, type DesignEditing } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}const groups = session.page.elements.filter((element): element is DesignEditing.GroupElement => element.type === "group");groups.forEach((group) => {// List all element types in the groupconst elementTypes = new Set<string>();group.contents.forEach((child) => {elementTypes.add(child.type);// Child positions are relative to the groupconsole.log(`${child.type} at relative position: ${child.top}, ${child.left}`);});console.log(`Group contains: ${Array.from(elementTypes).join(", ")}`);});});
Rect elements
Rect elements are rectangular shapes that can be filled with colors, images, or videos.
Creating rects with color fills
To create a rect with a solid color fill, use the colorContainer
property:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}const rectElementState =session.helpers.elementStateBuilder.createRectElement({top: 50,left: 50,width: 200,height: 150,rotation: 0,transparency: 0,fill: {colorContainer: {type: "solid",color: "#ff6b6b",},},});session.page.elements.insertAfter(undefined, rectElementState);await session.sync();});
Creating rects with image fills
To create a rect with an image fill, upload an image asset before setting that asset as the fill:
import { upload } from "@canva/asset";import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}const uploadResult = await upload({type: "image",url: "https://example.com/my-image.jpg",mimeType: "image/jpeg",thumbnailUrl: "https://example.com/my-image-thumbnail.jpg",aiDisclosure: "none",});const rectElementState =session.helpers.elementStateBuilder.createRectElement({top: 50,left: 50,width: 300,height: 200,fill: {mediaContainer: {type: "image",imageRef: uploadResult.ref,flipX: false,flipY: false,},},});session.page.elements.insertAfter(undefined, rectElementState);await session.sync();});
Creating rects with video fills
To create a rect with a video fill, upload a video asset before setting that asset as the fill:
import { upload } from "@canva/asset";import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}const uploadResult = await upload({type: "video",url: "https://example.com/my-video.mp4",mimeType: "video/mp4",thumbnailImageUrl: "https://example.com/video-thumbnail.jpg",thumbnailVideoUrl: "https://example.com/video-preview.mp4",aiDisclosure: "none",});const rectElementState =session.helpers.elementStateBuilder.createRectElement({top: 50,left: 50,width: 300,height: 200,fill: {mediaContainer: {type: "video",videoRef: uploadResult.ref,flipX: false,flipY: false,},},});session.page.elements.insertAfter(undefined, rectElementState);await session.sync();});
Shape elements
Shape elements are vector graphics defined by SVG-like paths. They support multiple paths with individual fills and strokes, enabling complex vector artwork.
Creating shape elements
To create a shape element, define one or more paths using SVG path syntax:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}const shapeElementState =session.helpers.elementStateBuilder.createShapeElement({top: 100,left: 100,width: 100,height: 100,viewBox: {top: 0,left: 0,width: 100,height: 100,},paths: [{d: "M 50 0 A 50 50 0 1 1 50 100 A 50 50 0 1 1 50 0 Z",fill: {colorContainer: {type: "solid",color: "#3498db",},},},],});session.page.elements.insertAfter(undefined, shapeElementState);await session.sync();});
Text elements
Text elements render formatted text content using richtext ranges, which support various formatting options and paragraph-level styling.
Creating text elements
To create a text element, define one or more text regions with content and formatting:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}const textElementState =session.helpers.elementStateBuilder.createTextElement({top: 50,left: 50,width: 300,rotation: 0,transparency: 0,text: {regions: [{text: "Hello, Canva!",formatting: {fontSize: 32,color: "#2c3e50",fontWeight: "bold",textAlign: "center",},},],},});session.page.elements.insertAfter(undefined, textElementState);await session.sync();});
Fills
A fill defines the interior appearance of a design ingredient. For example, apps can set the background of a page by setting its background to an image fill.
Ingredient types
The following types of ingredients can have fills:
- Backgrounds
- Rects
- Shapes
The way that fills are read and edited is consistent across each of these different types.
Fill types
The following types of fills are supported:
- Colors
- Images
- Videos
In the future, gradient fills will also be supported.
Reading fills
To check if an element has a color fill and read its value:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}// Read page background colorif (session.page.background?.colorContainer?.ref?.type === "solid") {const color = session.page.background.colorContainer.ref.color;console.log(`Background color: ${color}`);}// Read rect element colorssession.page.elements.forEach((element) => {if (element.type !== "rect") {return;}const colorFill = element.fill.colorContainer?.ref;if (colorFill?.type === "solid") {console.log(`Rect color: ${colorFill.color}`);}});// Read shape path colorssession.page.elements.forEach((element) => {if (element.type !== "shape") {return;}element.paths.forEach((path, index) => {const colorFill = path.fill.colorContainer?.ref;if (colorFill?.type === "solid") {console.log(`Path ${index} color: ${colorFill.color}`);}});});});
To check for image fills and access their properties:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}// Read page background imageconst bgMedia = session.page.background?.mediaContainer?.ref;if (bgMedia?.type === "image") {console.log(`Background image ref: ${bgMedia.imageRef}`);}// Read rect element imagessession.page.elements.forEach((element) => {if (element.type !== "rect") {return;}const media = element.fill.mediaContainer?.ref;if (media?.type === "image") {console.log(`Rect has image fill: ${media.imageRef}`);}});});
To check for video fills and access their properties:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute") {return;}// Read page background videoconst bgMedia = session.page.background?.mediaContainer?.ref;if (bgMedia?.type === "video") {console.log(`Background video ref: ${bgMedia.videoRef}`);}// Read shape path videossession.page.elements.forEach((element) => {if (element.type !== "shape") {return;}element.paths.forEach((path, index) => {const media = path.fill.mediaContainer?.ref;if (media?.type === "video") {console.log(`Path ${index} has video fill: ${media.videoRef}`);}});});});
Setting fills
Color fills are the simplest type of fill, consisting of a solid color specified as a hex code:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Set page background to a solid colorif (session.page.background) {session.page.background.colorContainer.set({type: "solid",color: "#f0f0f0",});}// Set rect element fills to colorssession.page.elements.forEach((element) => {if (element.type !== "rect" || element.locked) {return;}element.fill.colorContainer.set({type: "solid",color: "#ff00ff",});});// Set different colors for shape pathssession.page.elements.forEach((element) => {if (element.type !== "shape" || element.locked) {return;}element.paths.forEach((path, index) => {const colors = ["#ff0000", "#00ff00", "#0000ff"];path.fill.colorContainer.set({type: "solid",color: colors[index % colors.length],});});});await session.sync();});
Image fills require uploading an image asset first, then using the image reference:
import { upload } from "@canva/asset";import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Upload an image assetconst imageAsset = await upload({type: "image",url: "https://example.com/background.jpg",mimeType: "image/jpeg",thumbnailUrl: "https://example.com/background-thumb.jpg",aiDisclosure: "none",});// Set page background to an imageif (session.page.background) {session.page.background.mediaContainer.set({type: "image",imageRef: imageAsset.ref,flipX: false,flipY: false,});}// Set rect fills to imagessession.page.elements.forEach((element) => {if (element.type !== "rect" || element.locked) {return;}element.fill.mediaContainer.set({type: "image",imageRef: imageAsset.ref,flipX: true, // Flip horizontallyflipY: false,});});await session.sync();});
Video fills work similarly to image fills but use video assets:
import { upload } from "@canva/asset";import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Upload a video assetconst videoAsset = await upload({type: "video",url: "https://example.com/background-video.mp4",mimeType: "video/mp4",thumbnailImageUrl: "https://example.com/video-thumb.jpg",aiDisclosure: "none",});// Set page background to a videoif (session.page.background) {session.page.background.mediaContainer.set({type: "video",videoRef: videoAsset.ref,flipX: false,flipY: false,});}// Set shape fills to videos (if editable)session.page.elements.forEach((element) => {if (element.type !== "shape" || element.locked) {return;}element.paths.forEach((path) => {if (!path.fill.isMediaEditable) {return;}path.fill.mediaContainer.set({type: "video",videoRef: videoAsset.ref,flipX: false,flipY: false,});});});await session.sync();});
Clearing fills
To remove fills and make elements transparent, set the fill to undefined
:
import { openDesign } from "@canva/design";await openDesign({ type: "current_page" }, async (session) => {if (session.page.type !== "absolute" || session.page.locked) {return;}// Clear all fills from rect elementssession.page.elements.forEach((element) => {if (element.type !== "rect" || element.locked) {return;}// Remove both color and media fillselement.fill.colorContainer.set(undefined);element.fill.mediaContainer.set(undefined);});// Clear only media fill from page background (keep color)if (session.page.background) {session.page.background.mediaContainer.set(undefined);}await session.sync();});