On September 25th, 2024, we released v2 of the Apps SDK. To learn what’s new and how to upgrade, see Migration FAQ and Migration guide.

Elements

An introduction to elements in the Apps SDK.

In Canva, users can add elements to their designs.

An element is a container that holds some kind of content, such as image content, and can be arranged in a user's design, such as by setting its dimensions and position.

Apps can create and otherwise interact with elements in a variety of ways.

Elements vs. content

Content is the underlying media or text that exists within an element. Elements are a container with a specific set of dimensions that holds content. For example, a user uploads their image content into the image element on their design.

Content, however, does not always align with an element.

For example, a page background may contain image content, but the page background is not an image element. Similarly, a table cell may contain text content, but table cells are not text elements.

If your app needs to operate on the elements of a design, see the following sections and code samples, as well as the Design Editing guidelines for more information. If instead your app needs to edit the text, image, or video content found within the elements of a design, see the Content guide, and the Content Querying guidelines for more information.

Element types

Apps can interact with wide variety of element types, including:

To learn more about each element type, see the linked pages.

Additional types will be supported in the future.

App elements

There's a special type of element called an app element. An app element is essentially a group element with metadata attached to it. This metadata allows the app to create custom, re-editable elements.

Although app elements share characteristics with elements in general, they're unique enough that they're documented separately. To learn more, see App elements.

Creating elements

Apps can create elements by calling either of the following methods:

  • addElementAtPoint
  • addElementAtCursor

Both methods add an element to the user's design, but:

  • addElementAtPoint accepts an (optional) position and is only compatible with design types that support absolute positions, which is all design types except for documents.
  • addElementAtCursor doesn't accept a position and is only compatible with design types that contain streams of text, which is only the document design type.

The supported elements also depend on the method being called:

Element type
addElementAtPoint
addElementAtCursor
Embeds
Images
Groups
Shapes
Tables
Text
Richtext
Videos

Where possible, apps should determine the context in which the app is running and either call the compatible method or make it obvious when functionality isn't available:

import { Button, Rows } from "@canva/app-ui-kit";
import { addElementAtCursor, addElementAtPoint } from "@canva/design";
import { useFeatureSupport } from "utils/use_feature_support"; // https://github.com/canva-sdks/canva-apps-sdk-starter-kit/blob/main/utils/use_feature_support.ts
import * as styles from "styles/components.css";
export const App = () => {
const isSupported = useFeatureSupport();
function handleAddElementAtPoint() {
if (!isSupported(addElementAtPoint)) {
return;
}
addElementAtPoint({
type: "text",
children: ["Hello world"],
});
}
function handleAddElementAtCursor() {
if (!isSupported(addElementAtCursor)) {
return;
}
addElementAtCursor({
type: "text",
children: ["Hello world"],
});
}
return (
<div className={styles.scrollContainer}>
<Rows spacing="1u">
<Button
variant="primary"
onClick={handleAddElementAtPoint}
disabled={!isSupported(addElementAtPoint)}
>
Add element at point
</Button>
<Button
variant="primary"
onClick={handleAddElementAtCursor}
disabled={!isSupported(addElementAtCursor)}
>
Add element at cursor
</Button>
</Rows>
</div>
);
};
TSX

To learn more, see Feature support.

Positioning elements

The addElementAtPoint method accepts an optional set of dimensions and position:

import { addElementAtPoint } from "@canva/design";
// Upload an image asset
const asset = await upload({
type: "image",
mimeType: "image/jpeg",
url: "https://www.canva.dev/example-assets/image-import/image.jpg",
thumbnailUrl:
"https://www.canva.dev/example-assets/image-import/thumbnail.jpg",
aiDisclosure: "none"
});
// Add the image to the design
await addElementAtPoint({
type: "image",
ref: asset.ref,
top: 50,
left: 50,
width: 1280,
height: 720,
});
TSX

These properties must be used together or not at all. If a position isn't provided, the element is added to the center of the design.

Auto-calculating dimensions

You can set either the width or height properties to "auto":

import { addElementAtPoint } from "@canva/design";
// Upload an image asset
const asset = await upload({
type: "image",
mimeType: "image/jpeg",
url: "https://www.canva.dev/example-assets/image-import/image.jpg",
thumbnailUrl:
"https://www.canva.dev/example-assets/image-import/thumbnail.jpg",
aiDisclosure: "none"
});
// Add the image to the design
await addElementAtPoint({
type: "image",
ref: asset.ref,
top: 0,
left: 0,
width: 1280,
height: "auto",
});
TSX

This maintains the aspect ratio of the element without having to specify a pixel value.

Rotating elements

The addElementAtPoint method accepts a rotation:

import { addElementAtPoint } from "@canva/design";
// Upload an image asset
const asset = await upload({
type: "image",
mimeType: "image/jpeg",
url: "https://www.canva.dev/example-assets/image-import/image.jpg",
thumbnailUrl:
"https://www.canva.dev/example-assets/image-import/thumbnail.jpg",
aiDisclosure: "none"
});
// Add the image to the design
await addElementAtPoint({
type: "image",
ref: asset.ref,
top: 0,
left: 0,
width: 1280,
height: "auto",
rotation: 90,
});
TSX

This rotation only has an effect if the element has dimensions and a position.

Element traversal

Apps can traverse the elements in a user's design. This allows the app to read and update the structure of the design and the content of its elements. To learn more, see Design editing.