Content extensions
A content extension imports third-party content, such as photos and illustrations, into Canva. Users can access this content via the side panel and add it to their designs.
To create a content extension from scratch, check out the Quickstart guide.
Examples of content extensions
These are some examples of apps with content extensions:
- Brandfetch(opens in a new tab or window) - Easily add company logos to your design.
- Dropbox(opens in a new tab or window) - Add Dropbox photos to your designs.
- Giphy(opens in a new tab or window) - Add GIFs to your designs. Powered by GIPHY.
You can find more examples at canva.com/apps(opens in a new tab or window).
How users experience content extensions
Users can find apps with content extensions via the More tab.
When a user opens a content extension, the app is pinned to the left side of the screen and the content appears in the side panel. The user can then drag content into their design.
With additional configuration, a content extension can also:
- Let users search for content.
- Organize images into folders.
- Require authentication to access content.
How content extensions work
At its most basic, a content extension is a REST API.
Canva expects this API to have the following endpoint:
As a user interacts with a content extension via Canva's UI, Canva sends requests to this endpoint and expects to receive responses in a format that it understands. Based on these responses, Canva knows what content to render in the side panel.
Supported content types
A content extension can provide users with two types of content:
- Images, such as JPEG, PNG, and SVG files.
- Embeds, such as animated GIFs, YouTube videos, and Instagram photos.
Request-response cycle
This is the request-response cycle of a content extension:
Canva sends additional requests if the extension supports authentication.
Example
const axios = require("axios");const express = require("express");const app = express();app.use(express.json());app.use(express.static("public"));app.post("/content/resources/find", async (request, response) => {const { data } = await axios.get("https://picsum.photos/v2/list");const resources = data.map((resource) => {return {type: "IMAGE",id: resource.id,name: resource.author || resource.id,thumbnail: {url: resource.download_url,},url: resource.download_url,contentType: "image/jpeg",};});response.send({type: "SUCCESS",resources,});});app.listen(process.env.PORT || 3000);