Better Upload

Quickstart

You can setup file upload in your Next.js app in a few minutes with Better Upload. If you are using another framework or a backend server, check out Other Frameworks.

This guide will walk you through the steps to set it up with Next.js, but the steps are similar for other frameworks.

Prerequisites

Before you start, make sure you have the following:

  • A Next.js project.
  • An S3-compatible bucket. You can use AWS S3, Cloudflare R2, or any other.

Uploading your first image

Install

Install the better-upload package, as well as the AWS S3 Client.

npm install better-upload @aws-sdk/client-s3

Set up the Route Handler

The Route Handler will create pre-signed URLs, which the client uses to upload files directly to the S3 bucket. The recommended location for Next.js is app/api/upload/route.ts.

Change your-bucket-name to your S3 bucket name, and configure the S3 client as needed.

app/api/upload/route.ts
import { S3Client } from '@aws-sdk/client-s3';
import { createUploadRouteHandler, route } from 'better-upload/server';
 
const s3 = new S3Client(); 
 
export const { POST } = createUploadRouteHandler({
  client: s3,
  bucketName: 'your-bucket-name', 
  routes: {
    demo: route({
      fileTypes: ['image/*'],
    }),
  },
});

In the example above, we create the upload route demo. You can create routes for different purposes, like uploading multiple files at once. Learn more about upload routes here.

Create <Uploader /> component

We will now build our UI using pre-built components. We'll use <UploadButton /> for single file uploads.

Install it via the shadcn CLI:

npx shadcn@latest add "https://better-upload.js.org/r/upload-button.json"

We'll also use the useUploadFile hook. The complete code looks like this:

uploader.tsx
'use client';
 
import { useUploadFile } from 'better-upload/client';
import { UploadButton } from '@/components/ui/upload-button';
 
export function Uploader() {
  const { control } = useUploadFile({
    route: 'demo',
  });
 
  return <UploadButton control={control} accept="image/*" />;
}

There is also useUploadFiles for uploading multiple files. Learn more about the hooks here.

Place the component

Now place the <Uploader /> component in your app.

app/page.tsx
import { Uploader } from '@/components/uploader';
 
export default function Page() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center">
      <Uploader />
    </main>
  );
}

You're done! 🎉

You can now run your app and upload images directly to any S3-compatible service!

If you plan on uploading files larger than 5GB, take a look at multipart uploads.

Learn more

Concepts

Guides

Components

On this page