A simple react hook useUploadToS3 that levrage React Server Component to securely upload files to a private S3 bucket from the client while keeping the secret keys on the server.
This package works with Node.js, Bun, BrowsersIt is unknown whether this package works with Cloudflare Workers
Published
7 months ago (0.1.7)
useUploadToS3 - A simple React Hook to Upload to S3
A simple react hook useUploadToS3
that levrage React Server Component to securely upload files to a private S3 bucket from the client while keeping the secret keys on the server.
Installation
npx jsr add @dapofactory/react-hook-upload-to-s3
Usage
Configure S3 Bucket
- Create a private S3 bucket.
- Create a new IAM user with the following policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] }
- Save the
Access Key ID
andSecret Access Key
. - In the S3 console, add the following CORS configuration to your bucket → go to the bucket, Permissions tab, CORS configuration:
[ { "AllowedHeaders": ["*"], "AllowedMethods": ["PUT"], "AllowedOrigins": ["*"], "ExposeHeaders": [], "MaxAgeSeconds": 3000 } ]
Tip
You can restrain the AllowedOrigins
to your domain for greater security.
Add Environment Variables
- Create a
.env
file in the root of your project, with the following environment variables:
AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID> AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
Quickstart
'use client'; import { useUploadToS3 } from '@dapofactory/react-hook-upload-to-s3'; export default function UploadFile() { const [handleInputChange, s3key, isPending, error] = useUploadToS3( 'YOUR_BUCKET_NAME', 'YOUR_AWS_REGION' ); return ( <form> <input type='file' onChange={handleInputChange} /> <p>s3key: {s3key}</p> {isPending ? <p>Uploading...</p> : null} {error ? <p>Error: {error.message}</p> : null} </form> ); }
Note
handleInputChange
is a convenience function that makes all the magic happen. It triggers a call to a Server Action to create a secured URL to upload the file to S3.s3key
is the key of the file in the S3 bucket (so you can get it later).isPending
is a state that indicates if the file is being uploaded. As a state, it triggers a re-render when it changes.error
is a state that contains the error message if something goes wrong. It is also a state to be more convient to handle.
Motivations
- To provide a simple, efficient & secure way to upload files to a private S3 from the client.
- Makes everything that needs to be done on the server (using secrets, etc) to be done... on the server side !
- The upload is done from the client, so the file never touches the server.
- Circumvent the limitation on Vercel serverless functions to 4.5MB upload size.
- The hook is built with React Server Components, so it's generate a very small overhead in the bundle size on the client.
- It removes the need to make your S3 bucket public, and thus remove the need for a trade-off between security and convenience.
Add Package
npx jsr add @dapofactory/react-hook-upload-to-s3
Import symbol
import * as react_hook_upload_to_s_ from "@dapofactory/react-hook-upload-to-s3";
Add Package
yarn dlx jsr add @dapofactory/react-hook-upload-to-s3
Import symbol
import * as react_hook_upload_to_s_ from "@dapofactory/react-hook-upload-to-s3";
Add Package
pnpm dlx jsr add @dapofactory/react-hook-upload-to-s3
Import symbol
import * as react_hook_upload_to_s_ from "@dapofactory/react-hook-upload-to-s3";
Add Package
bunx jsr add @dapofactory/react-hook-upload-to-s3
Import symbol
import * as react_hook_upload_to_s_ from "@dapofactory/react-hook-upload-to-s3";