Updated March 31, 2026
8 min read
Image Upload & Storage
Upload, manage, and optimize images. Understand storage limits, quotas, and best practices.
Handover provides built-in image storage with automatic quota management. This guide covers the upload flow, storage limits, and best practices.
Upload Flow
The uploadImage() SDK method handles the complete three-step upload process automatically: request upload URL, upload to storage, save metadata.
const fileInput = document.querySelector("input[type=file]");
const file = fileInput.files[0];
try {
const result = await handover.uploadImage(
file,
sessionToken,
"Hero image for homepage" // optional alt text
);
console.log("Image uploaded:", result.url);
console.log("Image ID:", result.imageId);
} catch (error) {
if (error.code === "STORAGE_LIMIT_EXCEEDED") {
// Show upgrade prompt
}
}Storage Limits
Handover enforces storage quotas based on subscription tier. Uploads that exceed the limit are automatically rejected.
- Free tier: 100MB total storage
- Pro tier: 10GB total storage
- Storage is tracked per user across all projects
- Deleting images reclaims quota immediately
Supported File Types
Only image files are accepted. The SDK validates the MIME type before uploading.
- JPEG/JPG (image/jpeg)
- PNG (image/png)
- GIF (image/gif)
- WebP (image/webp)
- SVG (image/svg+xml)
Deleting Images
Remove unused images to free up storage quota. Deletion is immediate and cannot be undone.
await handover.deleteImage(imageId, sessionToken);
// Storage quota is updated immediatelyListing Images
Get all images for the project via getContent(). Each image includes URL, ID, and metadata.
const content = await handover.getContent();
content.images.forEach(image => {
console.log(image.url); // CDN URL
console.log(image._id); // Image ID
console.log(image.altText); // Alt text (optional)
console.log(image.mimeType); // e.g., "image/jpeg"
});Best Practices
Follow these guidelines to optimize storage usage and performance.
- Compress images before upload (use tools like TinyPNG)
- Use WebP format for better compression
- Delete unused images regularly
- Always provide alt text for accessibility
- Consider lazy loading for multiple images
- Use responsive images with srcset
This page maps to convex/images.ts in the repository.