Works with any backend npm install Zero dependencies

Error Handling Callbacks

Handle validation errors, upload errors, and task errors separately.

(function() {
 var logEl = document.getElementById('log');
 function log(m) { var d = document.createElement('div'); d.className='pkg-log-entry'; d.textContent=m; logEl.appendChild(d); logEl.scrollTop=logEl.scrollHeight; }
 new MultipleUpload('#demo', {
 uploadUrl: '/api/upload',
 multiple: true,
 maxFileSize: '1MB',
 allowedExtensions: '.jpg,.png,.pdf',
 onValidationError: function(msg, name) { log('[validation] ' + (name||'') + ': ' + msg); },
 onTaskError: function(task, err) { log('[taskError] ' + task.fileName + ': ' + err); },
 onError: function(msg, name) { log('[error] ' + (name||'general') + ': ' + msg); }
 });
})();

The catch-all

onError receives failures that are not tied to a single file's transfer — a network that vanished, a malformed response, a configuration problem. Per-file failures come through onTaskError, and validation rejections through onValidationError.

Say what to do next

The default toast is fine, but your own handler can be specific in a way a generic component cannot: whether retrying will help, whether the file was too large for a limit you know about, whether the user needs to sign in again. “Upload failed” tells someone only that they are stuck.