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.

Migration guide

How to upgrade to Apps SDK v2.

This guide explains all of the code changes required to upgrade to Apps SDK v2. For general information about migration, including deadlines, see the Migration FAQ.

Packages

All the npm packages for the Apps SDK have been updated with new TypeScript definitions. These definitions make it easier to identify what parts of your codebase need to be updated.

To install the updates, run the following command:

npm install @canva/asset@latest @canva/design@latest @canva/error@latest @canva/platform@latest @canva/user@latest
BASH

AI disclosure

In v2, an aiDisclosure property is required when uploading assets. This property indicates whether an asset was generated by AI, and helps maintain transparency about the origin of assets:

await upload({
type: "AUDIO",
title: "Example audio",
url: "https://www.canva.dev/example-assets/audio-import/audio.mp3",
mimeType: "audio/mp3",
aiDisclosure: "none", // => Or "app_generated"
});
TSX

Authentication

In v1, apps could use manual authentication to authenticate users via third-party platforms:

import { auth } from "@canva/user";
const response = await auth.requestAuthentication();
switch (response.status) {
case "COMPLETED":
console.log("The authentication was successful.");
break;
case "ABORTED":
console.log("The user exited the authentication flow.");
break;
case "DENIED":
console.log("The user didn't have the required permissions.");
break;
}
TSX

In v2, manual authentication has been deprecated.

Apps have two alternatives for authenticating users:

Feature support

Apps can now run in documents, but some APIs aren't compatible with documents.

In v1, there's no workaround for this. If an app uses incompatible APIs, it will be disabled for documents.

In v2, we've introduced the following methods:

  • isSupported
  • registerOnSupportChange

Apps can use these methods to check if a method is available in the current context. This allows the app to adapt to the context in which it's running.

For example, the following Add element at point button will be disabled if the app is running in a document, since the addElementAtPoint method (also introduced in v2) is not compatible with documents:

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.

Adding elements

In v1, elements could be added to a design with the addNativeElement method:

await addNativeElement({
type: "TEXT",
children: ["Hello world"],
});
TSX

In v2, this method has been deprecated and superseded by the following methods:

  • addElementAtPoint, which is a renamed version of addNativeElement.
  • addElementAtCursor, which is a new method that's compatible with documents.

These methods are only available in certain contexts and, as a result, apps should use the isSupported method to check that the methods are available in the current context before calling them:

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:

Asset IDs

In v1, the upload method accepted an id property:

await upload({
type: "IMAGE",
id: "exampleid",
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"
});
TSX

This property has been deprecated for a while and, in v2, it's been removed entirely:

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",
});
TSX

Audio asset duration

In v1, the upload method accepted a durationMs property for audio assets:

await upload({
type: "AUDIO",
title: "Example audio",
url: "https://www.canva.dev/example-assets/audio-import/audio.mp3",
mimeType: "audio/mp3",
durationMs: 86047,
aiDisclosure: "none",
});
TSX

In v2, this property has been deprecated and should not be used:

await upload({
type: "AUDIO",
title: "Example audio",
url: "https://www.canva.dev/example-assets/audio-import/audio.mp3",
mimeType: "audio/mp3",
aiDisclosure: "none",
});
TSX

Discriminators

In v1, some discrimintor values were uppercase:

await addNativeElement({
type: "EMBED",
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
});
TSX

In v2, all discriminator values are lowercase:

await addNativeElement({
type: "embed",
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
});
TSX

Drag and drop

In v1, apps could support drag and drop with the startDrag or makeDraggable methods:

ui.startDrag(event, {
type: "TEXT",
children: ["Add text into a design"],
});
TSX
ui.makeDraggable({
node,
dragData: {
type: "TEXT",
children: ["Hello world"],
},
onDragStart: () => {
console.log("The drag event has started");
},
onDragEnd: () => {
console.log("The drag event has ended");
},
});
TSX

In v2, startDrag has been deprecated and makeDraggable has been removed.

Instead, apps should use the following methods:

  • startDragToPoint
  • startDragToCursor

startDragToPoint is identical to startDrag, aside from the name, while startDragToCursor is a new method that's compatible with documents.

Because these methods are only available in certain contexts, apps should use the isSupported method to check that the methods are available in the current context.

To learn more, see:

Uploading assets

In v1, the queueMediaUpload and whenUploaded methods preceded the upload method. These methods have been deprecated for a while and have now been removed.

Apps should only upload assets with the upload method.