@uploadbox/react
v0.7.2
Published
React components and hooks for Uploadbox — UploadButton, UploadDropzone, useUploadbox
Maintainers
Readme
@uploadbox/react
React components and hooks for Uploadbox — UploadButton, UploadDropzone, and useUploadbox.
Installation
npm i @uploadbox/react @uploadbox/corePeer dependencies: React 18 or 19.
Quick Start
1. Wrap your app with the provider
import { UploadboxProvider } from "@uploadbox/react";
import "@uploadbox/react/styles.css";
export default function App({ children }) {
return (
<UploadboxProvider apiUrl="/api/uploadbox">
{children}
</UploadboxProvider>
);
}2. Add an upload component
import { UploadButton, UploadDropzone } from "@uploadbox/react";
function MyPage() {
return (
<>
<UploadButton
endpoint="imageUploader"
onClientUploadComplete={(files) => console.log("Uploaded:", files)}
onUploadError={(err) => console.error(err)}
/>
<UploadDropzone
endpoint="imageUploader"
onClientUploadComplete={(files) => console.log("Uploaded:", files)}
onUploadError={(err) => console.error(err)}
/>
</>
);
}useUploadbox Hook
For full control, use the hook directly:
import { useUploadbox } from "@uploadbox/react";
function CustomUploader() {
const {
startUpload, // (files: File[]) => Promise<UploadedFile[]>
isUploading, // boolean
progress, // 0–100
fileProgress, // FileProgress[] — per-file details
routeConfig, // fetched route constraints
abort, // cancel current upload
} = useUploadbox("imageUploader", {
onClientUploadComplete: (files) => console.log(files),
onUploadError: (err) => console.error(err),
onUploadProgress: (e) => {
console.log(`Overall: ${e.percent}%`);
e.fileProgress.forEach((f) => {
console.log(`${f.name}: ${f.percent}% — ${f.speed} B/s, ETA ${f.eta}s`);
});
},
});
return (
<div>
<input type="file" multiple onChange={(e) => startUpload([...e.target.files!])} />
{isUploading && <p>Uploading... {progress}%</p>}
<button onClick={abort} disabled={!isUploading}>Cancel</button>
</div>
);
}Per-File Progress
Each entry in fileProgress contains:
| Field | Type | Description |
|-------|------|-------------|
| name | string | File name |
| status | string | "pending" | "uploading" | "retrying" | "complete" | "error" |
| percent | number | 0–100 |
| speed | number | Bytes/sec (3-second sliding window) |
| eta | number | Estimated seconds remaining |
| retryCount | number | Number of retries so far |
| error | string? | Error message if failed |
Hook Options
useUploadbox("endpoint", {
onClientUploadComplete: (files) => {},
onUploadError: (err) => {},
onUploadProgress: (event) => {},
onBeforeUploadBegin: (files) => files, // transform files before upload
headers: { "x-custom": "value" },
getFileMetadata: (file) => ({ userId: "123" }),
ttlSeconds: 3600,
retry: { maxRetries: 5, initialDelayMs: 2000, backoffMultiplier: 2, maxDelayMs: 60000 },
// retry: false — to disable retries
});Customization
Content Props
Override default labels on built-in components:
<UploadButton
endpoint="imageUploader"
content={{ button: "Choose Image", allowedContent: "PNG, JPG up to 4MB" }}
/>
<UploadDropzone
endpoint="imageUploader"
content={{ label: "Drop files here", button: "Browse", allowedContent: "Images up to 4MB" }}
/>CSS Classes
All components accept a className prop. The default styles use these classes:
Button: .uploadbox-button, .uploadbox-progress-bar, .uploadbox-progress-bar-fill
Dropzone: .uploadbox-dropzone, .uploadbox-dropzone--dragover, .uploadbox-dropzone--uploading, .uploadbox-dropzone--complete, .uploadbox-dropzone--error
Styles
Import the default stylesheet:
import "@uploadbox/react/styles.css";Or write your own — the components work without the default CSS.
Type-Safe Factories
Generate components that are typed to your file router:
import { generateUploadButton, generateUploadDropzone } from "@uploadbox/react";
import type { AppRouter } from "@/lib/uploadbox";
const UploadButton = generateUploadButton<AppRouter>();
const UploadDropzone = generateUploadDropzone<AppRouter>();
// `endpoint` is now typed to your router keys
<UploadButton endpoint="imageUploader" />Multipart Uploads
Files larger than 10 MB are automatically uploaded in parts (10 MB each, 4 concurrent). No extra configuration needed — the hook and components handle this transparently.
Retry
Retries are enabled by default with exponential backoff:
// Default config
{
maxRetries: 3,
initialDelayMs: 1000,
backoffMultiplier: 2,
maxDelayMs: 30000,
}Retryable errors: network failures, 408, 429, and 5xx responses. Disable with retry: false.
Hosted Mode
For the Uploadbox hosted platform, pass an API key to the provider:
<UploadboxProvider apiUrl="/api/uploadbox" apiKey="pk_live_xxx">
{children}
</UploadboxProvider>Related Packages
@uploadbox/core— Core utilities, builder pattern, S3 operations@uploadbox/nextjs— Next.js route handler adapter
License
MIT
