Creating images
Apps can add images to a user's design, such as PNG or SVG files. The user can then arrange and manipulate those images with the Canva tooling they've come to know and love.
The user experience
When an app adds an image to the user's design, the image file is uploaded to the user's media library.
The user's media library has a storage quota. If the user has a Canva Pro account, their storage quota is 1TB. Otherwise, their storage quota is 5GB. If the user exceeds the storage quota, they'll see an error.
Once the image exists in the user's design, the image is indistinguishable from images added via Canva's built-in features. This means the user can manipulate the image in all the same ways, including:
- Adjusting the size, position, and rotation of the image
- Applying effects to the image
- Using the image as a background
- Animating the image — for example, having it fade in
Supported image types
Apps can add the following types of images to a user's design:
The maximum file size for images is 25MB.
Data URLs vs. external URLs
When creating images, the image data can be provided as a data URL or an external URL. The chosen format affects both the user and developer experience.
Data URLs
A data URL is a URI scheme that allows you to include data in-line in web pages as if they were external resources. For example, a data URL representation of a PNG image looks something like this:
data:image/png;base64,iVBORw0KGg...
To learn more, see the MDN documentation.
Pros
- It's the most convenient way to generate images at runtime
- There's less code required to create images from data URLs
Cons
- The image data is downloaded via Canva's frontend, which is slower
- In some cases, data URLs can increase an app's bundle size
External URLs
An external URL is any URL that points to a file hosted on a third-party server. Generally speaking, we recommend that apps use external URLs as they offer the best user experience.
Pros
- The image data is downloaded via Canva's backend, which is the fastest option
- There's no risk of increasing the app's bundle size
Cons
- Creating images from external URLs requires more code
- There are strict requirements for external URLs
How to create images from data URLs
Step 1: Create a data URL
There are various ways for an app to create data URLs. This section explores a couple of the most common options: importing the images and using the Canvas API.
Importing images
In the starter kit, images can be imported directly into the app's source code:
import dog from "../assets/dog.jpg";console.log(dog); // => data:image/jpeg;base64,/9j/4AA...
The imported images are immediately available as data URLs.
This is suitable for small image files that must be loaded for most users, such as thumbnail images. The downside is that it increases the size of the JavaScript bundle, which increases the app's load time.
Using the Canvas API
You can use the Canvas API to generate images from scratch or apply effects to existing images. For example, the following function returns a data URL for a gradient image:
function createGradient(color1: string, color2: string): string {const canvas = document.createElement("canvas");canvas.width = 640;canvas.height = 360;const ctx = canvas.getContext("2d");if (!ctx) {throw new Error("Can't get CanvasRenderingContext2D");}const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);gradient.addColorStop(0, color1);gradient.addColorStop(1, color2);ctx.fillStyle = gradient;ctx.fillRect(0, 0, canvas.width, canvas.height);return canvas.toDataURL();}
Step 2: Add the image to the design
Import the addNativeElement
method from the @canva/design
package:
import { addNativeElement } from "@canva/design";
Call the method, passing in the options shown here:
await addNativeElement({type: "IMAGE",dataUrl: createGradient("#ff0099", "#0000ff"),});
How to create images from external URLs
Step 1: Upload an image from a URL
Import the upload
method from the @canva/asset
package:
import { upload } from "@canva/asset";
Call the method, passing in the options shown here:
const result = await upload({type: "IMAGE",id: "uniqueidgoeshere",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",});
When uploading images:
- The
id
property must contain a unique identifier that always points to the same file. This ensures that Canva doesn't upload duplicate files to the user's account. - The URLs must be exposed via the internet and available to Canva's backend, as Canva needs access to the URLs to download them. This means you can't use
localhost
URLs.
The upload
method returns an object that contains a ref
property:
console.log(result.ref);
This property contains a reference, which is a unique identifier that points to an image asset in Canva's backend. An app can use this reference to interact with the file — even while it's uploading.
Step 2: Add the image to the design
Import the addNativeElement
method from the @canva/design
package:
import { addNativeElement } from "@canva/design";
Call the method, passing in the options shown here:
await addNativeElement({type: "IMAGE",ref: result.ref,});
Additional considerations
- All images must comply with Canva's Acceptable Use Policy.
- All images must comply with Canva's Upload formats and requirements.
API reference
Code sample
Data URL
import React from "react";import { addNativeElement } from "@canva/design";export function App() {async function handleClick() {// Add the image to the designawait addNativeElement({type: "IMAGE",dataUrl: createGradient("#ff0099", "#0000ff"),});}return (<div><button onClick={handleClick}>Add image from data URL</button></div>);}function createGradient(color1: string, color2: string): string {const canvas = document.createElement("canvas");canvas.width = 640;canvas.height = 360;const ctx = canvas.getContext("2d");if (!ctx) {throw new Error("Can't get CanvasRenderingContext2D");}const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);gradient.addColorStop(0, color1);gradient.addColorStop(1, color2);ctx.fillStyle = gradient;ctx.fillRect(0, 0, canvas.width, canvas.height);return canvas.toDataURL();}
External URL
import React from "react";import { upload } from "@canva/asset";import { addNativeElement } from "@canva/design";export function App() {async function handleClick() {// Upload an imageconst result = await upload({type: "IMAGE",id: "uniqueidgoeshere",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",});// Add the image to the designawait addNativeElement({type: "IMAGE",ref: result.ref,});}return (<div><button onClick={handleClick}>Add image from external URL</button></div>);}