Search
Add a search field to a content extension.
A content extension can be configured to include a search field. This allows users to find exactly the content they're looking for.
This topic explains how to receive and handle search queries.
By default, content extensions don't support search. You need to enable the feature.
To enable search for a content extension:
  1. 1.
    Navigate to an app via the Developer Portal
  2. 2.
    On the Extensions page, expand the Content panel.
  3. 3.
    Select the Display search field checkbox.

Step 2: Receive search requests

When a user performs a search, Canva sends a POST request to the following URL:
1
<base_url>/content/resources/find
Copied!
This is the same URL that Canva sends requests to when requesting images, embeds, and containers. The only difference is that the body of this request includes a query property that contains the user's search query:
1
{
2
"user": "AUQ2RUzug9pEvgpK9lL2qlpRsIbn1Vy5GoEt1MaKRE=",
3
"brand": "AUQ2RUxiRj966Wsvp7oGrz33BnaFmtq4ftBeLCSHf8=",
4
"label": "CONTENT",
5
"limit": 100,
6
"type": "IMAGE",
7
"locale": "en-US",
8
"query": "funny cats"
9
}
Copied!
When a POST request is not triggered by a search, the query property is null. You can therefore detect when a user has performed a search by checking if the value of the query property is null:
1
app.post("/content/resources/find", async (request, response) => {
2
if (request.body.query) {
3
// the user has performed a search
4
}
5
6
if (!request.body.query) {
7
// the user has not performed a search
8
}
9
});
Copied!

Step 4: Respond to search requests

When a user performs a search, a content extension should return a "SUCCESS" response that includes resources relevant to the user's query:
1
{
2
"type": "SUCCESS",
3
"resources": []
4
}
Copied!
What counts as "relevant" depends on what you're trying to accomplish. Your extension could just return resources that have the user's exact search query in their name property. Or after users perform a search, you could keep track of what resources they drag into their designs and then use that data to surface the most relevant resources for future searches. It's your choice.
If a search returns more results than can be included in a single response, use pagination to load the additional resources.

Step 5: Handle containers

If an extension supports containers, it's important to know that the query and containerId properties are mutually exclusive. If the query property is not null, then the containerId will be null. This means a user cannot search within a container. You can, however, use a search query to return a filtered list of containers.

Example

This example allows users to search for photos from Pixabay. You'll need a (free) API key to run it.
1
const axios = require("axios");
2
const express = require("express");
3
const app = express();
4
5
app.use(express.json());
6
app.use(express.static("public"));
7
8
app.post("/content/resources/find", async (request, response) => {
9
// Configure the request
10
const options = {
11
url: "https://pixabay.com/api/",
12
params: {
13
key: process.env.PIXABAY_API_KEY,
14
},
15
};
16
17
// If a user has provided a query, include it in the request
18
if (request.body.query) {
19
options["params"]["q"] = request.body.query;
20
}
21
22
// Send a request to Pixabay
23
const pixabay = await axios.request(options);
24
25
// Transform the array of images into an array of "IMAGE" resources
26
const images = pixabay.data.hits.map((image) => {
27
return {
28
type: "IMAGE",
29
id: image.id,
30
name: `Photo by ${image.user}`,
31
thumbnail: {
32
url: image.webformatURL,
33
height: image.webformatHeight,
34
width: image.webformatWidth,
35
},
36
contentType: "image/jpeg",
37
url: image.webformatURL,
38
};
39
});
40
41
// Return a "SUCCESS" response
42
response.send({
43
type: "SUCCESS",
44
resources: images,
45
});
46
});
47
48
app.listen(process.env.PORT || 3000);
Copied!
Last modified 18d ago