Containers
When creating a content extension, one of the available options for the Content type field is Containers. If you select this option, the extension can organize content into containers (folders).
Request-response cycle
For the most part, containers work the same way as the other content types. There are, however, a couple of details that affect the request-response cycle:
Canva always requests containers in separate HTTP requests from the other types of content. For example, if you configure a content extension to support images, embeds, and containers, Canva will send one request for the images and embeds, and a different request for the containers.
When a user selects a container, Canva includes a containerId
property in both requests. The extension can use this ID to respond with content and sub-containers that belong to the selected container. This is demonstrated in the example.
Notes
- You can assign thumbnails to containers. This thumbnail should represent or provide an example of the container's contents.
- For additional requirements that apply to this content type, see Choose the best content types.
Limitations
- You can't submit an app for review if it has a content extension that only supports containers. This is because an extension that only supports containers isn't useful.
- If a content extension supports search, containers appear in search results, but users can't search for content inside specific containers.
Example
const axios = require("axios");const express = require("express");const app = express();app.use(express.json());app.use(express.static("public"));if (!process.env.PIXABAY_API_KEY) {throw new Error("The PIXABAY_API_KEY environment variable is not set");}app.post("/content/resources/find", async (request, response) => {// Handle "CONTAINER" requestsif (request.body.types.includes("CONTAINER")) {// The user has opened a containerif (request.body.containerId) {response.send({type: "SUCCESS",resources: [],});}// The user has not opened a containerif (!request.body.containerId) {response.send({type: "SUCCESS",resources: [{type: "CONTAINER",id: "animals",name: "Animals",},{type: "CONTAINER",id: "food",name: "Food",},{type: "CONTAINER",id: "people",name: "People",},],});}}// Handle "IMAGE" requestsif (request.body.types.includes("IMAGE")) {// Configure the requestconst options = {url: "https://pixabay.com/api/",params: {key: process.env.PIXABAY_API_KEY,},};// The user has opened a containerif (request.body.containerId) {options.params.category = request.body.containerId;}// Send the requestconst pixabay = await axios.request(options);// Transform the array of images into an array of "IMAGE" resourcesconst images = pixabay.data.hits.map((image) => {return {type: "IMAGE",id: image.id,name: `Photo by ${image.user}`,thumbnail: {url: image.webformatURL,height: image.webformatHeight,width: image.webformatWidth,},url: image.webformatURL,contentType: "image/jpeg",};});// Provide a success responseresponse.send({type: "SUCCESS",resources: images,});}});app.listen(process.env.PORT || 3000);