Uploading media

How to upload media to a user's media library?

Apps can use the Content capability to upload media to a user's media library. This guide explains how to upload media, add the media to a design, and detect when the media has finished uploading.

Step 1: Initialize the Content capability

Like all capabilities, Canva injects the Content capability into the app's iframe and attaches it to the window object:

console.log(window.canva.content);

To access the capability, import and call the getContent function:

import { getContent } from "@canva/content";
const content = getContent();
console.log(content); // => Content

This function:

  • Throws an error if the capability is unavailable
  • Provides type-safety when using TypeScript

Step 2: Start the upload process

At some point in the lifecycle of the app, such when a user clicks a button, call the queueMediaUpload method. The accepted properties for this method depend on the type of media being uploaded:

  • Images
  • Videos

The following snippet demonstrates how to upload image files:

const upload = await content.queueMediaUpload({
type: "IMAGE",
mimeType: "image/jpeg",
id: "P3z7hP2",
url: "https://i.imgur.com/P3z7hP2.jpg",
thumbnailUrl: "https://i.imgur.com/Bh4gjjL.png",
});

This method tells Canva to start uploading the media from the provided URL. It returns a Promise that immediately resolves with a media reference or an error:

if (upload.type === "done") {
console.log(upload.ref);
} else {
throw new Error(`Unexpected response type: ${upload.reason.type}`);
}

A media reference is an ID that's generated by Canva and points to media in the user's media library. Apps can pass this reference into certain methods to use and interact with the media — even before the media has finished uploading.

Step 3: Add the media to the user's design

Once some media has been uploaded, it's typical for the app to add the media to the user's design. This can be done with the Design Interaction capability.

To add the media to the user's design:

  1. Initialize the Design Interaction capability:

    import { getDesignInteraction } from "@canva/design-interaction";
    const designInteraction = getDesignInteraction();
  2. Call either the addNativeElement or registerRenderAppElement method, but pass in a media reference instead of a data URL:

    // Native element
    designInteraction.addNativeElement({
    type: "IMAGE",
    ref: upload.ref,
    });
    // App element
    designInteraction.registerRenderAppElement((data) => {
    return [
    {
    type: "IMAGE",
    ref: data.ref,
    top: 0,
    left: 0,
    width: 640,
    height: 427,
    },
    ];
    });
    designInteraction.setAppElementData({
    ref: upload.ref,
    });

If the media reference is used before the full-sized media has finished uploading, the thumbnail is shown as a placeholder.

(Optional) Step 4: Detect when the upload is complete

The queueMediaUpload method returns an whenUploaded method that returns a Promise. This Promise resolves when the media has finished uploading or an error occurs.

You can use the whenUploaded method to detect when an upload is complete:

const result = await upload.whenUploaded();
if (result.type === "done") {
console.log("The upload is complete!");
} else {
throw new Error(`Unexpected response type: ${result.reason.type}`);
}

Example

import { getContent } from "@canva/content";
import { getDesignInteraction } from "@canva/design-interaction";
import React from "react";
export const App = () => {
const content = getContent();
const designInteraction = getDesignInteraction();
const handleClick = async () => {
// Start uploading the media
const upload = await content.queueMediaUpload({
type: "IMAGE",
mimeType: "image/jpeg",
id: "P3z7hP2",
url: "https://i.imgur.com/P3z7hP2.jpg",
thumbnailUrl: "https://i.imgur.com/Bh4gjjL.png",
});
if (upload.type !== "done") {
throw new Error(`Unexpected response type: ${upload.type}`);
}
// Add the media to the design
designInteraction.addNativeElement({
type: "IMAGE",
ref: upload.ref,
});
// Do something when the upload is done
const result = await upload.whenUploaded();
if (result.type === "done") {
console.log("The media has finished uploading!");
} else {
throw new Error(`Unexpected response type: ${result.reason.type}`);
}
};
return <button onClick={handleClick}>Import media</button>;
};