Appearance
Building Your First App
Complete walkthrough from idea to published app.
1. Concept and Planning
Before writing code, define:
- What does your app do? One sentence description
- Who is it for? Your target user
- What type of app? Content import, design manipulation, data connector, generative AI
- Authentication needed? Yes if you access external services
2. Environment Setup
bash
# Install CLI
npm install -g @canva/cli@latest
# Login
canva login
# Create app
canva apps create "My First App"
# Select template (e.g., Hello World)
# Follow prompts...3. Project Structure
After setup, your project contains:
my-app/
├── src/
│ └── app.tsx # Main app component
├── backend/
│ └── server.ts # Backend server (if applicable)
├── canva-app.json # App configuration
├── package.json
└── tsconfig.json4. Building the UI
Use App UI Kit components:
tsx
import { Button, Rows, Text } from "@canva/app-ui-kit";
export function App() {
return (
<Rows spacing="1u">
<Text>Hello from my app!</Text>
<Button variant="primary" onClick={handleClick}>
Do Something
</Button>
</Rows>
);
}5. Adding SDK Calls
Interact with Canva's editor:
tsx
import { addNativeElement } from "@canva/design";
async function addTextToDesign() {
await addNativeElement({
type: "TEXT",
children: ["Hello, Canva!"],
fontSize: 24,
});
}6. Testing
bash
# Start dev server
npm run start
# In Canva editor:
# Apps > Your Apps > [Your app name] (development)7. Preparing for Submission
- Run
npm run build— fix any build errors - Complete the submission checklist
- Prepare app listing assets (icon, featured image)
- Write clear description
- Submit via developer portal
Common Patterns
Fetch and display content
tsx
const [items, setItems] = useState([]);
useEffect(() => {
async function load() {
const token = await auth.getCanvaUserToken();
const res = await fetch("/api/items", {
headers: { Authorization: `Bearer ${token}` }
});
setItems(await res.json());
}
load();
}, []);Add image to design
tsx
import { upload } from "@canva/asset";
import { addNativeElement } from "@canva/design";
async function addImage(url: string) {
const asset = await upload({
type: "image",
url,
mimeType: "image/jpeg",
thumbnailUrl: url,
width: 800,
height: 600,
});
await addNativeElement({
type: "IMAGE",
ref: asset.ref,
});
}