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.

initAppElement

API reference for the initAppElement method.
This version of the API is a preview. Preview APIs are unstable and may change without warning. You can't release public apps using this API until it's stable.

Usage

Initialize app element client

import { initAppElement } from "@canva/design";
const appElement = initAppElement<{ content: string }>({
render: (data) => {
return [{
type: 'text',
children: [data.content],
top: 100,
left: 100,
width: 200
}];
}
});
TYPESCRIPT

Initialize V2 app element client

import { initAppElement } from "@canva/design";
const appElement = initAppElement<{ content: string }>({
render: (data) => {
return [{
type: 'text',
children: [data.content],
top: 100,
left: 100,
width: 200
}];
}
});
TYPESCRIPT

Parameters

appElementConfigAppElementClientConfiguration<A>
Required

Configuration for an AppElementClient

renderAppElementRenderer<A>
Required

Registers a callback that renders an app element based on the data it receives.

Parameters

appElementDataA
Required

The data the callback must use to render the app element.

A primitive data type that can be used in app element data.

All primitive data types are supported except for symbols and bigints.

An object primitive data type that can be used in app element data.

Returns

An array of one or more elements to render as output of an app element.

AppElementRendererOutput

Returns

A client that provides methods for creating and managing the lifecycle of an app element.

addOrUpdateElementfunction

This type has been superseded, use addElement or registerOnElementChange instead. If an app element is selected, the element's data is overwritten and the element is re-rendered. Otherwise, the provided data is used to create a new app element.

Parameters

appElementDataA
Required

The data to attach to the app element. Existing data will be overwritten.

A primitive data type that can be used in app element data.

All primitive data types are supported except for symbols and bigints.

An object primitive data type that can be used in app element data.

placementPlacement
Optional

The position, dimensions, and rotation of the app element.

topnumber
Required

The distance from the top edge of the container, in pixels.

  • The pixels are relative to their container.

Minimum: -32768

Maximum: 32767

leftnumber
Required

The distance from the left edge of the container, in pixels.

  • The pixels are relative to their container.

Minimum: -32768

Maximum: 32767

widthnumber
Required

A width, in pixels.

  • The pixels are relative to their container.

Minimum: 0

Maximum: 32767

heightnumber
Required

A height, in pixels.

  • The pixels are relative to their container.

Minimum: 0

Maximum: 32767

rotationnumber
Optional

A rotation, in degrees.

Minimum: -180

Maximum: 180

Returns

Promise<void>

Examples

Create or update an element (deprecated)

import { initAppElement } from "@canva/design";
// Initialize the app element client
const appElement = initAppElement<{ content: string; timestamp: number }>({
render: (data) => {
return [{
type: 'text',
children: [data.content || 'Default text'],
top: 100,
left: 100,
width: 200
}];
}
});
// Create a new element or update selected element
await appElement.addOrUpdateElement({
content: 'Hello from the app',
timestamp: Date.now()
});
TYPESCRIPT

Update with specific placement (deprecated)

import { initAppElement } from "@canva/design";
const appElement = initAppElement<{ content: string }>({
render: (data) => {
return [{
type: 'text',
children: [data.content || 'Default text'],
top: 0,
left: 0,
width: 200
}];
}
});
// Create or update with specific placement
await appElement.addOrUpdateElement(
{
content: 'Positioned content'
},
{
top: 200,
left: 200,
width: 300,
height: 100
}
);
TYPESCRIPT
addElementfunction

Adds a new app element to the design.

Parameters

optsAppElementOptions<A>
Required

The data and placement of the app element.

dataA
Required

The data to attach to the app element.

A primitive data type that can be used in app element data.

All primitive data types are supported except for symbols and bigints.

An object primitive data type that can be used in app element data.

placementPlacement
Optional

The position, dimensions, and rotation of the app element.

topnumber
Required

The distance from the top edge of the container, in pixels.

  • The pixels are relative to their container.

Minimum: -32768

Maximum: 32767

leftnumber
Required

The distance from the left edge of the container, in pixels.

  • The pixels are relative to their container.

Minimum: -32768

Maximum: 32767

widthnumber
Required

A width, in pixels.

  • The pixels are relative to their container.

Minimum: 0

Maximum: 32767

heightnumber
Required

A height, in pixels.

  • The pixels are relative to their container.

Minimum: 0

Maximum: 32767

rotationnumber
Optional

A rotation, in degrees.

Minimum: -180

Maximum: 180

Returns

Promise<void>

Examples

Add new element with data

import { initAppElement } from "@canva/design";
const appElement = initAppElement<{ content: string; id: string }>({
render: (data) => {
return [{
type: 'text',
children: [data.content || 'Default text'],
top: 0,
left: 0,
width: 200
}];
}
});
// Add a new element
await appElement.addElement({
data: {
content: 'New element content',
id: 'element-' + Date.now()
}
});
TYPESCRIPT

Add element with specific placement

import { initAppElement } from "@canva/design";
const appElement = initAppElement<{
title: string;
description: string;
createdAt: number;
}>({
render: (data) => {
return [{
type: 'text',
children: [data.title || 'Default title'],
top: 0,
left: 0,
width: 300,
fontWeight: 'bold',
fontSize: 24
}, {
type: 'text',
children: [data.description || 'Default description'],
top: 50,
left: 0,
width: 300
}];
}
});
// Add element with specific placement
await appElement.addElement({
data: {
title: 'Element Title',
description: 'This is a description of the element',
createdAt: Date.now()
},
placement: {
top: 100,
left: 100,
width: 400,
height: 150,
rotation: 0
}
});
TYPESCRIPT
registerOnElementChangefunction

A callback that runs when:

  • the app element is created
  • the app element's data is updated
  • the user selects an existing app element

Parameters

handlerAppElementChangeHandler<A>
Required

The callback to run when the app element changes.

Parameters

appElementobject | undefined
Required

Information about the app element that was changed.

dataA
Required

The app element data in its most recent state.

A primitive data type that can be used in app element data.

All primitive data types are supported except for symbols and bigints.

An object primitive data type that can be used in app element data.

versionnumber
Required

The version number of the app.

updatefunction
Required

Function to update the app element data.

Examples

Update element data only

if (element) {
await element.update({
data: {
...element.data,
content: 'Updated content',
lastUpdated: Date.now()
}
});
}
TYPESCRIPT

Update data and placement

if (element) {
await element.update({
data: {
...element.data,
content: 'Positioned element'
},
placement: {
top: 200,
left: 200,
width: 300,
height: 100
}
});
}
TYPESCRIPT

Add metadata to element

if (element) {
await element.update({
data: {
...element.data,
metadata: {
...(element.data.metadata || {}),
lastEdited: Date.now(),
editCount: (element.data.metadata?.editCount || 0) + 1,
},
},
});
}
TYPESCRIPT

Parameters

optsAppElementOptions<A>
Required

The data and placement to update the app element with.

dataA
Required

The data to attach to the app element.

A primitive data type that can be used in app element data.

All primitive data types are supported except for symbols and bigints.

An object primitive data type that can be used in app element data.

placementPlacement
Optional

The position, dimensions, and rotation of the app element.

topnumber
Required

The distance from the top edge of the container, in pixels.

  • The pixels are relative to their container.

Minimum: -32768

Maximum: 32767

leftnumber
Required

The distance from the left edge of the container, in pixels.

  • The pixels are relative to their container.

Minimum: -32768

Maximum: 32767

widthnumber
Required

A width, in pixels.

  • The pixels are relative to their container.

Minimum: 0

Maximum: 32767

heightnumber
Required

A height, in pixels.

  • The pixels are relative to their container.

Minimum: 0

Maximum: 32767

rotationnumber
Optional

A rotation, in degrees.

Minimum: -180

Maximum: 180

Returns

Promise<void>

Returns

void

Returns

void

Examples

Handle element selection and update

import { initAppElement } from "@canva/design";
const appElement = initAppElement<{ content: string }>({
render: (data) => {
return [{
type: 'text',
children: [data.content || 'Default text'],
top: 0,
left: 0,
width: 200
}];
}
});
// Register a handler for element changes
appElement.registerOnElementChange((element) => {
if (element) {
// Element is created or selected
// Optionally update the element
// element.update({
// data: { ...element.data, lastSelected: Date.now() }
// });
} else {
// No element is selected
}
});
TYPESCRIPT

Update element when selected

import { initAppElement } from "@canva/design";
const appElement = initAppElement<{
content: string;
metadata: { created: number; lastSelected: number };
}>({
render: (data) => {
// Render based on data
return [{
type: 'text',
children: [data.content || ''],
top: 0,
left: 0,
width: 200
}];
}
});
// Update element when selected
appElement.registerOnElementChange(async (element) => {
if (element) {
// Check if this is a newly created or a selected element
const isNewElement = !element.data.metadata?.created;
if (isNewElement) {
// Update a new element with initial metadata
await element.update({
data: {
...element.data,
metadata: {
created: Date.now(),
lastSelected: Date.now()
}
}
});
} else {
// Update existing element's last selected time
await element.update({
data: {
...element.data,
metadata: {
...element.data.metadata,
lastSelected: Date.now()
}
}
});
}
}
});
TYPESCRIPT