@uploadjoy/react
The @uploadjoy/react package contains the hooks and components for building upload UIs with React.
useInput
The useInput hook is a React hook that provides a helpers and configuration for building a file input component.
Basic Usage
Assuming you have a file router set up, you can use the useInput hook to build a file input component.
import { useInput } from "@uploadjoy/react/hooks";
import type { OurFileRouter } from "@/server/uploadjoy";
export function MyComponent() {
  const { getInputProps, openFileDialog, upload } = useInput<OurFileRouter>({
    endpoint: "imageUploader",
    clientCallbacks: {
      onUploadSuccess: (ctx) => {
        console.log(ctx);
      },
    },
  });
  return (
    <>
      <input {...getInputProps()} />
      <button
        onClick={openFileDialog}
        className="m-2 rounded-md bg-indigo-700 p-2"
      >
        Pick Files
      </button>
      <button
        onClick={() => upload()}
        className="m-2 rounded-md bg-slate-700 p-2"
      >
        Upload
      </button>
    </>
  );
}
You must provide the type of your file router to the generic type parameter of
the useInput hook. This is used to provide type safety.
Configuration
The useInput hook accepts a configuration object with the following properties:
- Name
- disabled
- Type
- boolean (optional)
- Description
- Sets the - disabledattribute on the input element.
 
- Name
- onFileDialogCancel
- Type
- () => void; (optional)
- Description
- Function to call when the file dialog is cancelled. 
 
- Name
- onFileDialogOpen
- Type
- () => void; (optional)
- Description
- Function to call when the file dialog is opened. 
 
- Name
- onFileDialogError
- Type
- (error: Error) => void; (optional)
- Description
- Function to call when the file dialog encounters an error. 
 
- Name
- endpoint
- Type
- string (required)
- Description
- The name of a route configured in the file router to use for the upload. If you correctly provided the type of your file router to the generic type parameter of the - useInputhook, this will be type checked against the routes you configured.
 
- Name
- clientCallbacks
- Type
- ClientCallbacks (optional)
- Description
- An object containing callbacks to be called on the client. See the type definitions below for more information. - type ClientOnUploadCallback = (input: { file: File; access: "private" | "public"; }) => Promise<void> | void; type ClientOnUploadFailureCallback = (input: { file: File; access: "private" | "public"; }) => Promise<void> | void; type ClientOnUploadProgressCallback = (input: { file: File; access: "private" | "public"; uploadProgress: Pick<ProgressEvent, "loaded" | "total">; }) => Promise<void> | void; type ClientCallbacks = { onUpload?: ClientOnUploadCallback; onUploadFailure?: ClientOnUploadFailureCallback; onUploadProgress?: ClientOnUploadProgressCallback; };
 
Returns
The useInput hook returns an object with the following properties:
- Name
- getInputProps
- Type
- function
- Description
- Returns an object containing the props to be spread on the input element. 
 
- Name
- openFileDialog
- Type
- () => void
- Description
- Opens the file dialog. 
 
- Name
- upload
- Type
- () => Promise<void>
- Description
- Uploads the selected files. 
 
- Name
- reset
- Type
- () => void
- Description
- Resets the input element. 
 
- Name
- readyToUpload
- Type
- boolean
- Description
- Whether or not the input element is ready to upload files based on if presigned URLs have been fetched. 
 
- Name
- isUploading
- Type
- boolean
- Description
- Whether or not files are being uploaded. 
 
useDropzone
The useDropzone hook is a React hook that provides a helpers and configuration for building a dropzone component.
Basic Usage
Assuming you have a file router set up, you can use the useInput hook to build a file input component.
import type { OurFileRouter } from "@/server/uploadjoy";
import { useDropzone } from "@uploadjoy/react/hooks";
export const Dropzone = () => {
  const { getInputProps, openFileDialog, upload, getDropzoneRootProps } =
    useDropzone<OurFileRouter>({
      endpoint: "imageUploader",
      clientCallbacks: {
        onUploadSuccess: (ctx) => {
          console.log("onUploadSuccess", ctx);
        },
      },
    });
  return (
    <div>
      <h2 className="mb-3 text-xl font-medium">Dropzone Component</h2>
      <div
        // Spread the props on the root element of your dropzone component
        {...getDropzoneRootProps()}
        className="mb-2 flex h-[200px] w-[200px] flex-col items-center
        justify-center rounded-md border border-dashed border-indigo-500 hover:cursor-pointer
        focus:border-white"
        onClick={() => openFileDialog()}
      >
        <p className="text-slate-500">Drag and Drop here!</p>
        <p className="text-sm text-slate-500">or click to open file dialog</p>
        {/* Spread the props for the file input component */}
        <input {...getInputProps()} />
      </div>
      <div className="flex gap-4">
        <button
          onClick={() => upload()}
          className="w-fit rounded-md bg-slate-700 p-2"
        >
          Upload
        </button>
      </div>
    </div>
  );
};
You must provide the type of your file router to the generic type parameter of
the useDropzone hook. This is used to provide type safety.
Configuration
The useDropzone hook accepts a configuration object with the following properties:
- Name
- disabled
- Type
- boolean (optional)
- Description
- Sets the - disabledattribute on the input element.
 
- Name
- onFileDialogCancel
- Type
- () => void; (optional)
- Description
- Function to call when the file dialog is cancelled. 
 
- Name
- onFileDialogOpen
- Type
- () => void; (optional)
- Description
- Function to call when the file dialog is opened. 
 
- Name
- onFileDialogError
- Type
- (error: Error) => void; (optional)
- Description
- Function to call when the file dialog encounters an error. 
 
- Name
- onDragEnter
- Type
- () => void; (optional)
- Description
- Function to call when the - dragenterevent is fired on the dropzone.
 
- Name
- onDragLeave
- Type
- () => void; (optional)
- Description
- Function to call when the - dragleaveevent is fired on the dropzone.
 
- Name
- onDragOver
- Type
- () => void; (optional)
- Description
- Function to call when the - dragoverevent is fired on the dropzone.
 
- Name
- onDrop
- Type
- () => void; (optional)
- Description
- Function to call when the - dropevent is fired on the dropzone.
 
- Name
- endpoint
- Type
- string (required)
- Description
- The name of a route configured in the file router to use for the upload. If you correctly provided the type of your file router to the generic type parameter of the - useInputhook, this will be type checked against the routes you configured.
 
- Name
- clientCallbacks
- Type
- ClientCallbacks (optional)
- Description
- An object containing callbacks to be called on the client. See the type definitions below for more information. - type ClientOnUploadCallback = (input: { file: File; access: "private" | "public"; }) => Promise<void> | void; type ClientOnUploadFailureCallback = (input: { file: File; access: "private" | "public"; }) => Promise<void> | void; type ClientOnUploadProgressCallback = (input: { file: File; access: "private" | "public"; uploadProgress: Pick<ProgressEvent, "loaded" | "total">; }) => Promise<void> | void; type ClientCallbacks = { onUpload?: ClientOnUploadCallback; onUploadFailure?: ClientOnUploadFailureCallback; onUploadProgress?: ClientOnUploadProgressCallback; };
 
Returns
The useDropzone hook returns an object with the following properties:
- Name
- getInputProps
- Type
- function
- Description
- Returns an object containing the props to be spread on the file input element. 
 
- Name
- getDropzoneRootProps
- Type
- function
- Description
- Returns an object containing the props to be spread on the root element of your dropzone component. 
 
- Name
- openFileDialog
- Type
- () => void
- Description
- Opens the file dialog. 
 
- Name
- upload
- Type
- () => Promise<void>
- Description
- Uploads the selected files. 
 
- Name
- reset
- Type
- () => void
- Description
- Resets the input element. 
 
- Name
- readyToUpload
- Type
- boolean
- Description
- Whether or not the input element is ready to upload files based on if presigned URLs have been fetched. 
 
- Name
- isUploading
- Type
- boolean
- Description
- Whether or not files are being uploaded. 
 
useUploadjoy
If you want to build a more custom upload component, @uploadjoy/react exposes a useUploadjoy hook that provides a lot of the same functionality as the useInput and useDropzone hooks.
Basic Usage
Assuming you have a file router set up, you can generate the useUploadjoy hook for your file router and use it to build a file input component.
import { generateReactHelpers } from "@uploadjoy/react/hooks";
import type { OurFileRouter } from "@/server/uploadjoy";
import { useState } from "react";
import { PresignedUrlRequestResponse } from "@uploadjoy/core/client";
const { useUploadjoy } = generateReactHelpers<OurFileRouter>();
export const CustomComponentWithHelpers = () => {
  const [files, setFiles] = useState<File[]>([]);
  const [presignedUrls, setPresignedUrls] = useState<
    PresignedUrlRequestResponse | undefined
  >(undefined);
  const {
    isUploading,
    fetchPresignedUrls,
    startUpload,
    permittedFileInfo,
    getMimeTypesFromConfig,
  } = useUploadjoy({ endpoint: "imageUploader" });
  return (
    <div>
      <h2 className="mb-3 text-xl font-medium">
        Custom Component with Helpers
      </h2>
      {permittedFileInfo && (
        <div>
          <input
            type="file"
            onChange={async (e) => {
              setFiles(Array.from(e.target.files ?? []));
              const presignedUrls = await fetchPresignedUrls({
                files: Array.from(e.target.files ?? []),
              });
              setPresignedUrls(presignedUrls);
            }}
            accept={getMimeTypesFromConfig(permittedFileInfo.config).join(",")}
          />
          {presignedUrls && (
            <button
              onClick={() =>
                startUpload({
                  presignedUrls,
                  files,
                  clientCallbacks: {
                    onUploadSuccess: (ctx) => {
                      console.log("onUploadSuccess", ctx);
                    },
                  },
                })
              }
              disabled={isUploading}
            >
              {isUploading ? "Uploading..." : "Upload"}
            </button>
          )}
        </div>
      )}
    </div>
  );
};
We import generateReactHelpers from @uploadjoy/react/hooks and provide our file router type as a generic type parameter. This will type check the useUploadjoy hook against the routes we configured in our file router.
Configuration
The useUploadjoy hook accepts an object with the following properties:
- Name
- endpoint
- Type
- string
- Description
- File router endpoint to use for the upload. 
 
Returns
The useUploadjoy hook returns an object with the following properties:
- Name
- fetchPresignedUrls
- Type
- function
- Description
- A function you can call to fetch presigned URLs for the files you wish to upload. 
 
- Name
- startUpload
- Type
- function
- Description
- A function you can call to start uploading files. 
 
- Name
- isUploading
- Type
- boolean
- Description
- Whether or not files are being uploaded. 
 
- Name
- isFetchingPresignedUrls
- Type
- boolean
- Description
- Whether or not presigned URLs are being fetched. 
 
- Name
- permittedFileInfo
- Type
- PermittedFileInfo
- Description
- Information about the permitted files and config based on the configured route. - See the source for more information. 
 
- Name
- getMimeTypesFromConfig
- Type
- function
- Description
- A helper function you can call to get the mime types from the router config in - permittedFileInfo.