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:
-
Initialize the Design Interaction capability:
import { getDesignInteraction } from "@canva/design-interaction";const designInteraction = getDesignInteraction(); -
Call either the
addNativeElement
orregisterRenderAppElement
method, but pass in a media reference instead of a data URL:// Native elementdesignInteraction.addNativeElement({type: "IMAGE",ref: upload.ref,});// App elementdesignInteraction.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 mediaconst 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 designdesignInteraction.addNativeElement({type: "IMAGE",ref: upload.ref,});// Do something when the upload is doneconst 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>;};