useUpload
Upload files to S3 with progress tracking, callbacks, and reactive state.
useUpload handles single-file uploads using presigned URLs. It validates the file locally, requests a presigned URL from the server, and uploads the file directly to S3.
Basic Usage
components/upload.tsx
import { storageClient } from "@/lib/storage-client";
const { useUpload } = storageClient;
function UploadForm() {
const { state, upload, reset } = useUpload({
onSuccess: (result) => {
console.log("Uploaded:", result.key);
},
});
const handleSubmit = async (file: File) => {
await upload(file, { userId: "u_1" });
};
return (
<div>
{state.isLoading && <p>Uploading: {Math.round(state.progress * 100)}%</p>}
{state.status === "error" && <p>Error: {state.error?.message}</p>}
{state.status === "success" && <p>Uploaded to: {state.data?.key}</p>}
<button onClick={reset}>Reset</button>
</div>
);
}Options
| Option | Type | Description |
|---|---|---|
onProgress | (progress: number) => void | Called with upload progress from 0 to 1 |
onSuccess | (result: UploadFileResult) => void | Called when the upload completes |
onError | (error: StorageError) => void | Called when the upload fails |
throwOnError | boolean | Override the client-level throwOnError setting |
State
| Field | Type | Description |
|---|---|---|
status | "idle" | "loading" | "success" | "error" | Current upload status |
isLoading | boolean | true while uploading |
progress | number | Upload progress from 0 to 1 |
data | UploadFileResult | null | Upload result on success |
error | StorageError | null | Error details on failure |
Methods
| Method | Signature | Description |
|---|---|---|
upload | (file: File, metadata: T) => Promise<void> | Start the upload. Metadata is typed from your server schema. |
reset | () => void | Reset state back to idle |
Upload Result
On success, state.data contains:
type UploadFileResult = {
key: string; // Generated S3 key
presignedUrl: string; // The presigned URL used
uploadUrl: string; // Actual upload URL
status: number; // HTTP status (e.g. 200)
statusText: string; // HTTP status text
uploadHeaders?: Record<string, string>;
};Upload Flow
- Validates file locally (size, name, type).
- Sends file info and metadata to the server's
/upload-urlendpoint. - Receives a presigned URL and optional upload headers.
- Uploads the file directly to S3 via XHR with progress tracking.
- Returns the result with the generated key.
Next Steps
- useMultipartUpload for files that benefit from chunked uploads.
- Encryption to encrypt files at rest.
- Error Handling for error patterns and
throwOnError.