@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
disabled
attribute 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
useInput
hook, 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
disabled
attribute 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
dragenter
event is fired on the dropzone.
- Name
onDragLeave
- Type
- () => void; (optional)
- Description
Function to call when the
dragleave
event is fired on the dropzone.
- Name
onDragOver
- Type
- () => void; (optional)
- Description
Function to call when the
dragover
event is fired on the dropzone.
- Name
onDrop
- Type
- () => void; (optional)
- Description
Function to call when the
drop
event 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
useInput
hook, 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
.