Image elements
Add image elements to designs with editing capabilities.
Running this example
To run this example locally:
-
If you haven't already, create a new app in the Developer Portal(opens in a new tab or window). For more information, refer to our Quickstart guide.
-
In your app's configuration on the Developer Portal(opens in a new tab or window), ensure the "Development URL" is set to
http://localhost:8080. -
Clone the starter kit:
git clone https://github.com/canva-sdks/canva-apps-sdk-starter-kit.gitcd canva-apps-sdk-starter-kitSHELL -
Install dependencies:
npm installSHELL -
Run the example:
npm run start:example image_elementsSHELL -
Click the Preview URL link shown in the terminal to open the example in the Canva editor.
Example app source code
// For usage information, see the README.md file./* eslint-disable no-restricted-imports */// ESLint rule is disabled to allow importing static assets for demonstrationimport {Box,Button,FormField,Grid,ImageCard,Rows,Text,} from "@canva/app-ui-kit";import cat from "assets/images/cat.jpg";import dog from "assets/images/dog.jpg";import rabbit from "assets/images/rabbit.jpg";import { useState, useCallback } from "react";import * as styles from "styles/components.css";import { upload } from "@canva/asset";import { addElementAtCursor, addElementAtPoint } from "@canva/design";import { useFeatureSupport } from "@canva/app-hooks";// Static image data for demonstration - in production, use hosted assetsconst images = {dog: {title: "Dog",imageSrc: dog,},cat: {title: "Cat",imageSrc: cat,},rabbit: {title: "Rabbit",imageSrc: rabbit,},};export const App = () => {const [dataUrl, setDataUrl] = useState(dog);const [isLoading, setIsLoading] = useState(false);const isSupported = useFeatureSupport();const addElement = [addElementAtPoint, addElementAtCursor].find((fn) =>isSupported(fn),);const disabled = !dataUrl || dataUrl.trim().length < 1;const items = Object.entries(images).map(([key, value]) => {const { title, imageSrc } = value;return {key,title,imageSrc,active: dataUrl === imageSrc,onClick: () => {setDataUrl(imageSrc);},};});const addImage = useCallback(async () => {if (!addElement) {return;}setIsLoading(true);try {// Upload the image to Canva's asset system and get a reference// This creates a reusable asset that can be used in multiple designsconst { ref } = await upload({type: "image",mimeType: "image/jpeg",url: dataUrl,thumbnailUrl: dataUrl,// AI disclosure indicates whether AI was used to create this contentaiDisclosure: "none",});// Add the uploaded image as a design element to the current page// The element will appear at the default position on the design canvasawait addElement({type: "image",ref, // Reference to the uploaded assetaltText: {text: "photo of an animal",decorative: undefined, // Set to true if image is purely decorative},});} finally {setIsLoading(false);}}, [dataUrl, addElement]);return (<div className={styles.scrollContainer}><Rows spacing="2u"><Text>This example demonstrates how apps can add image elements to a design.</Text><FormFieldlabel="Select an image"control={({ id }) => (<Box id={id} padding="1u"><Grid columns={3} spacing="1.5u">{items.map((item) => (<ImageCardariaLabel="Add image to design"alt={item.title}key={item.key}thumbnailUrl={item.imageSrc}onClick={item.onClick}selectable={true}selected={item.active}borderRadius="standard"/>))}</Grid></Box>)}/><Buttonvariant="primary"disabled={disabled || !addElement}tooltipLabel={!addElement? "This feature is not supported in the current page": undefined}loading={isLoading}onClick={addImage}stretch>Add element</Button></Rows></div>);};
TYPESCRIPT
// For usage information, see the README.md file.import { AppUiProvider } from "@canva/app-ui-kit";import { createRoot } from "react-dom/client";import { App } from "./app";import "@canva/app-ui-kit/styles.css";import type { DesignEditorIntent } from "@canva/intents/design";import { prepareDesignEditor } from "@canva/intents/design";async function render() {const root = createRoot(document.getElementById("root") as Element);root.render(<AppUiProvider><App /></AppUiProvider>,);}const designEditor: DesignEditorIntent = { render };prepareDesignEditor(designEditor);// Hot Module Replacement for development (automatically reloads the app when changes are made)if (module.hot) {module.hot.accept("./app", render);}
TYPESCRIPT
# Image elements exampleThis example demonstrates how to add image elements to a design.For API reference docs and instructions on running this example, see: https://www.canva.dev/docs/apps/examples/image-elements/.See also the App image elements example: https://www.canva.dev/docs/apps/examples/app-image-elements/. Using app elements instead of regular design elements allows for more complex app interactions and behaviors.NOTE: This example differs from what is expected for public apps to pass a Canva review:- Static assets are used for demonstration purposes only. Production apps should host assets on a CDN/hosting service and use the `upload` function from the `@canva/asset` package- ESLint rule `no-restricted-imports` is disabled for example purposes only. Production apps should not disable linting rules without proper justification- Error handling is simplified for demonstration. Production apps must implement comprehensive error handling with clear user feedback and graceful failure modes- Internationalization is not implemented. Production apps must support multiple languages using the `@canva/app-i18n-kit` package to pass Canva review requirements- The code structure is simplified: Production apps using [intents](https://www.canva.dev/docs/apps/intents/) are recommended to call the prepareDesignEditor function from src/intents/design_editor/index.tsx
MARKDOWN
API reference
Need help?
- Join our Community Forum(opens in a new tab or window)
- Report issues with this example on GitHub(opens in a new tab or window)