SuperUpload
v1.0.0 · Last updated April 2026
Drag-and-drop file uploads with image previews, chunked uploads for large files, client-side validation, and server integration.
# Basic Usage
HTML
<div data-az-component="super-upload"
data-az-url="/api/upload"
data-az-name="files">
<!-- Drop Zone -->
<div data-az-dropzone>
<p>Drag files here or <span data-az-upload-trigger>browse</span></p>
</div>
<!-- Hidden file input (auto-created if not present) -->
<input type="file" data-az-upload-input multiple>
<!-- File List -->
<div data-az-upload-list></div>
</div>
Configuration Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| data-az-url | string | — | Upload endpoint URL |
| data-az-name | string | "file" | Form field name for uploads |
| data-az-multiple | boolean | true | Allow multiple files |
| data-az-auto-upload | boolean | true | Upload immediately on selection |
| data-az-method | string | "POST" | HTTP method for upload |
| data-az-headers | JSON | {} | Extra request headers |
| data-az-parallel | number | 2 | Concurrent uploads |
# File Validation
Client-side validation before upload begins.
HTML
<div data-az-component="super-upload"
data-az-url="/api/upload"
data-az-accept="image/*,.pdf"
data-az-max-size="10MB"
data-az-max-files="5"
data-az-min-files="1">
...
</div>
Validation Attributes
| Attribute | Description | Example |
|---|---|---|
| data-az-accept | Allowed file types (MIME or extension) | image/*,.pdf,.docx |
| data-az-max-size | Max file size per file | 10MB, 500KB, 1GB |
| data-az-max-total | Max total size of all files | 50MB |
| data-az-max-files | Max number of files | 5 |
| data-az-min-files | Min required files | 1 |
| data-az-min-dimensions | Min image dimensions | 800x600 |
| data-az-max-dimensions | Max image dimensions | 4096x4096 |
Custom Error Messages
HTML
<div data-az-component="super-upload"
data-az-accept="image/*"
data-az-max-size="5MB"
data-az-message-type="Please upload images only"
data-az-message-size="File must be under 5MB">
...
</div>
# File Previews
Automatic thumbnails for images and icons for other file types.
HTML
<div data-az-component="super-upload"
data-az-url="/api/upload"
data-az-preview="true"
data-az-preview-max-width="200"
data-az-preview-max-height="200">
<div data-az-dropzone>...</div>
<!-- File list with preview template -->
<div data-az-upload-list>
<!-- SuperUpload clones this for each file -->
<template data-az-file-template>
<div class="file-item">
<img data-az-file-preview alt="">
<span data-az-file-name></span>
<span data-az-file-size></span>
<div data-az-file-progress></div>
<button data-az-file-remove>Remove</button>
<span data-az-file-error></span>
</div>
</template>
</div>
</div>
File Template Parts
| Attribute | Description |
|---|---|
| data-az-file-preview | Image preview thumbnail (src set automatically) |
| data-az-file-name | Displays file name |
| data-az-file-size | Displays formatted file size (e.g., "2.5 MB") |
| data-az-file-type | Displays MIME type or extension |
| data-az-file-progress | Progress bar container (width set to %) |
| data-az-file-progress-text | Upload progress as text (e.g., "45%") |
| data-az-file-remove | Button to remove file from queue |
| data-az-file-retry | Button to retry failed upload |
| data-az-file-error | Error message display |
| data-az-file-status | Status indicator (pending/uploading/done/error) |
# Chunked Upload
Upload large files in chunks with automatic resume capability.
HTML
<div data-az-component="super-upload"
data-az-url="/api/upload"
data-az-chunked="true"
data-az-chunk-size="5MB"
data-az-resumable="true">
...
</div>
Chunked Upload Attributes
| Attribute | Default | Description |
|---|---|---|
| data-az-chunked | false | Enable chunked uploads |
| data-az-chunk-size | 5MB | Size of each chunk |
| data-az-resumable | true | Enable resume after failure |
| data-az-chunk-retries | 3 | Retry attempts per chunk |
Server Protocol
Request Headers
Content-Range: bytes 0-5242879/15728640
X-Upload-Id: abc123
X-Chunk-Number: 1
X-Total-Chunks: 3
X-File-Name: video.mp4
# HTMX Integration
Trigger HTMX swaps after successful uploads.
HTML
<div data-az-component="super-upload"
data-az-url="/api/upload"
hx-trigger="az:upload:complete"
hx-get="/partials/gallery"
hx-target="#gallery"
hx-swap="innerHTML">
...
</div>
<div id="gallery">
<!-- Gallery refreshed after upload -->
</div>
Server Response
JSON Response
{
"success": true,
"file": {
"id": "file_abc123",
"name": "photo.jpg",
"size": 1048576,
"url": "https://cdn.example.com/uploads/photo.jpg",
"thumbnailUrl": "https://cdn.example.com/uploads/photo_thumb.jpg"
}
}
# Direct Upload (Pre-signed URLs)
Upload directly to cloud storage (S3, GCS) using pre-signed URLs.
HTML
<div data-az-component="super-upload"
data-az-presign-url="/api/presign"
data-az-callback-url="/api/upload-complete">
...
</div>
Flow
1
Request Pre-signed URL
SuperUpload POSTs file metadata to data-az-presign-url
2
Server Returns Upload URL
Your server generates a pre-signed URL from cloud provider
3
Direct Upload to Cloud
SuperUpload PUTs the file directly to S3/GCS (bypasses your server)
4
Callback to Your Server
SuperUpload POSTs completion data to data-az-callback-url
Pre-sign Response Format
JSON
{
"uploadUrl": "https://storage.googleapis.com/bucket/path?signature=...",
"method": "PUT",
"headers": {
"Content-Type": "image/jpeg"
},
"fileId": "file_xyz789"
}
# Events
| Event | Description | Detail |
|---|---|---|
| az:upload:add | File added to queue | { file } |
| az:upload:remove | File removed from queue | { file } |
| az:upload:start | Upload started | { file } |
| az:upload:progress | Upload progress update | { file, loaded, total, percent } |
| az:upload:success | Single file uploaded | { file, response } |
| az:upload:error | Upload failed | { file, error } |
| az:upload:complete | All files in queue processed | { files, successful, failed } |
| az:upload:validate | Validation failed (cancelable) | { file, errors } |
Example: Track All Uploads
JavaScript
document.addEventListener('az:upload:complete', (e) => {
const { files, successful, failed } = e.detail;
if (failed.length > 0) {
SuperToaster.error(`${failed.length} files failed to upload`);
} else {
SuperToaster.success(`${successful.length} files uploaded!`);
}
// Refresh gallery
htmx.trigger('#gallery', 'refresh');
});