We are currently working on a new version of the documentation.

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

OptionTypeDescription
onProgress(progress: number) => voidCalled with upload progress from 0 to 1
onSuccess(result: UploadFileResult) => voidCalled when the upload completes
onError(error: StorageError) => voidCalled when the upload fails
throwOnErrorbooleanOverride the client-level throwOnError setting

State

FieldTypeDescription
status"idle" | "loading" | "success" | "error"Current upload status
isLoadingbooleantrue while uploading
progressnumberUpload progress from 0 to 1
dataUploadFileResult | nullUpload result on success
errorStorageError | nullError details on failure

Methods

MethodSignatureDescription
upload(file: File, metadata: T) => Promise<void>Start the upload. Metadata is typed from your server schema.
reset() => voidReset 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

  1. Validates file locally (size, name, type).
  2. Sends file info and metadata to the server's /upload-url endpoint.
  3. Receives a presigned URL and optional upload headers.
  4. Uploads the file directly to S3 via XHR with progress tracking.
  5. Returns the result with the generated key.

Next Steps