Media & Imaging - Integration Guide
Overview
The Media & Imaging system handles all image uploads for Malets โ product photos, service images, banners, and more. It features progressive loading with blur-up placeholders, direct-to-cloud uploads via presigned URLs, and optional AI-powered background removal.
Quick Start
Uploading Images
The MediaUploader component is used throughout the management interface (product creation, service editing, blog posts, etc.):
- Click the "+ Add Media" button or drag and drop files onto the upload area
- Watch the circular progress ring as the file uploads directly to cloud storage
- After upload, the server processes the image (generates thumbnails, blur placeholder)
- The image appears with a smooth blur-to-sharp transition
Supported Formats
| Format | Extension | Notes |
|---|---|---|
| JPEG | .jpg |
Best for photos |
| PNG | .png |
Best for graphics/transparency |
| WebP | .webp |
Modern, smaller file sizes |
| GIF | .gif |
Animated images supported |
| AVIF | .avif |
Next-gen compression |
| SVG | .svg |
Vector graphics |
Size limit: 10 MB per file
AI Background Removal
When uploading product images, enable the "Remove BG" toggle to automatically remove the background:
- Toggle the checkbox before uploading
- Upload your image normally
- The server's AI model processes the image during confirmation
- Result: clean product image with transparent background and adaptive shadow
Progressive Image Loading
How It Works
Every image across the Ngwenya platform uses progressive loading for a polished experience:
- Instant: A tiny, blurred version (LQIP โ Low Quality Image Placeholder) renders immediately
- Loading: The full-resolution image loads in the background
- Transition: A smooth 400ms cross-fade reveals the sharp image
If no blur placeholder is available, a shimmer animation plays instead.
Image Uploader
Upload Flow (Presigned S3)
The upload process is secure and efficient โ files go directly to cloud storage without passing through the app server:
โโโโโโโโโโโ 1. requestUploadUrl โโโโโโโโโโโโ
โ Browser โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโถ โ Media โ
โ โ โโโโโ {uploadUrl, fileId} โโ โ Service โ
โ โ โโโโโโโโโโโโ
โ โ 2. PUT file
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโถ โโโโโโโโโโโโ
โ โ โโโโโ 200 OK โโโโโโโโโโโโโ โ S3 โ
โ โ โโโโโโโโโโโโ
โ โ 3. confirmUpload(fileId) โโโโโโโโโโโโ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโถ โ Media โ
โ โ โโโโโ MediaFile โโโโโโโโโโ โ Service โ
โโโโโโโโโโโ โโโโโโโโโโโโ
MediaUploader Component (Frontend)
<script>
import MediaUploader from '$lib/components/manage/MediaUploader.svelte';
let images = [];
</script>
<MediaUploader
bind:images
label="Product Images"
maxImages={10}
maletId="your-malet-id"
allowBackgroundRemoval={true}
on:change={(e) => console.log('Updated:', e.detail)}
/>
GraphQL Operations
requestUploadUrl (Mutation)
Request a presigned S3 upload URL:
mutation RequestUploadUrl($input: RequestUploadUrlInput!) {
requestUploadUrl(input: $input) {
uploadUrl # Presigned PUT URL (expires in 1 hour)
fileId # Unique ID for confirmation step
expiresAt # ISO timestamp
}
}
confirmUpload (Mutation)
Confirm the upload and trigger processing:
mutation ConfirmUpload($fileId: String!) {
confirmUpload(fileId: $fileId) {
id
url # Public CDN URL
blurDataUrl # Base64 LQIP (for ProgressiveImage)
thumbnails {
label
url
width
height
}
metadata {
width
height
format
size
}
status # PENDING โ COMPLETE
}
}
Integration Checklist
Progressive Image Loading
- Render
ProgressiveImagewithblurDataUrlโ verify blur placeholder visible - Wait for image to load โ verify smooth cross-fade transition
- Render without
blurDataUrlโ verify shimmer animation plays - Test with broken
srcโ verify error placeholder appears
Image Uploader
- Click "+ Add Media" โ verify file dialog opens
- Select a valid image โ verify progress ring appears
- After processing โ verify image thumbnail appears in the grid
- Drag and drop files โ verify drop zone highlight and upload
- Reach
maxImageslimit โ verify "+ Add Media" button disappears
AI Background Removal
- Enable "Remove BG" toggle before uploading
- Upload a product photo โ verify processing takes slightly longer
- Verify result has transparent/clean background
Environment Variables
| Variable | Description |
|---|---|
STORAGE_PROVIDER |
s3 or local |
UPLOAD_DIR |
Local directory for file uploads (if provider is local) |
LOCAL_STORAGE_URL |
Base URL for serving local files |
S3_ENDPOINT |
Custom endpoint for S3-compatible storage (e.g., R2, MinIO) |
S3_REGION |
S3 bucket region |
S3_BUCKET |
Target S3 bucket name |
S3_ACCESS_KEY |
AWS Access Key ID |
S3_SECRET_KEY |
AWS Secret Access Key |
S3_PUBLIC_URL |
Public CDN URL for serving S3 objects |
MAX_FILE_SIZE |
Maximum allowed file size in bytes |
ALLOWED_MIMETYPES |
Comma-separated list of allowed MIME types |