Uploading custom icons
You can use any of our public icons when creating your content, but you can also upload your own.
The icon upload process works as follows:
- Send your image file to the Yoto API
- Receive back an identifier
- Use the identifier in your playlist
In this example, we’ll be uploading the motorbike emoji icon from the Noto Emoji set.
Upload your icon
Section titled “Upload your icon”import { readFileSync } from "node:fs";const iconBuffer = readFileSync("./emoji-motorbike.png");
const iconFile = new Blob([iconBuffer]);
const formData = new FormData();formData.append("file", iconFile);
const url = new URL( "https://api.yotoplay.com/media/displayIcons/user/me/upload");url.searchParams.set("autoConvert", "true");url.searchParams.set("filename", "emoji-motorbike");
const uploadResponse = await fetch(url, { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, }, body: formData,});
const uploadResult = await uploadResponse.json();
Upload parameters
Section titled “Upload parameters”You can customize the upload behavior with these query parameters:
-
autoConvert
(boolean): When set totrue
(recommended), Yoto will automatically resize and process your image to 16×16 pixels. If set tofalse
, your image must already be exactly 16×16 pixels in PNG or GIF format. -
filename
(string): Optional custom filename for your icon. The file extension will be automatically determined from the uploaded file’s MIME type.
Using your uploaded icon
Section titled “Using your uploaded icon”Once uploaded successfully, you’ll receive a response containing:
{ "displayIcon": { "mediaId": "XBkuY6DBFn5iRfFS6nV6CTWaCrEvBOOX8nzV9Y64h8I", "userId": "auth0|userHash", "displayIconId": "683736c62fd7c5cd177d206f", "url": "https://media-secure.aws.com/icons/mlWc6s-JG", "new": true }}
The mediaId
is what you’ll use in your content. Reference it with the yoto:#
prefix:
const chapters = [ { key: "01", title: "Chapter 1", display: { icon16x16: `yoto:#${mediaId}`, // Your custom icon }, tracks: [ { key: "01", title: "Track 1", display: { icon16x16: `yoto:#${mediaId}`, // Same icon for track }, // ... rest of track data }, ], },];
Your custom icon will now display on your Yoto player when this content is playing!
Here’s an example of a complete workflow:
export const createCustomIconCard = async ({ iconFile, filename = "my-custom-icon", title = "Custom Icon Streaming Card", streamUrl = "https://yoto.dev/music/autumn-3.mp3", cardId, accessToken,}) => { // Step 1: Upload the custom icon
// Construct URL with query parameters const url = `https://api.yotoplay.com/media/displayIcons/user/me/upload?autoConvert=true&filename=${filename}`;
// Upload the icon file const uploadResponse = await fetch(url, { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "image/png", }, body: iconFile, });
const uploadResult = await uploadResponse.json();
// The response should contain the mediaId const { mediaId } = uploadResult.displayIcon;
console.log("Icon uploaded successfully:", { mediaId, });
// Step 2: Create streaming card content using the uploaded icon
const chapters = [ { key: "01", title: title, overlayLabel: "1", tracks: [ { key: "01", type: "stream", format: "mp3", title: title, trackUrl: streamUrl, display: { icon16x16: `yoto:#${mediaId}`, // Using the uploaded icon }, }, ], display: { icon16x16: `yoto:#${mediaId}`, // Using the uploaded icon }, }, ];
const content = { title: title, content: { chapters }, metadata: { description: `Streaming card with custom ${filename} icon`, }, };
if (cardId) { // specify a cardId to update an existing card content.cardId = cardId; }
// Step 3: Create the card with the custom icon const createResponse = await fetch("https://api.yotoplay.com/content", { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify(content), });
const card = await createResponse.json();
console.log("Streaming card created successfully with custom icon!");
return card;};