Supabase Storage upload, drag and drop

The free upload dropzone with Supabase Storage as its uploader. Errors land on the file's row with a retry button. MIT.

Get it freeOpen the demoReact · Tailwind · TypeScript

Use it in Next.js

app/upload/page.tsx

"use client";
import UploadDropzone, { type Uploader } from "@/components/upload-dropzone/UploadDropzone";
import { createClient } from "@/lib/supabase/client";

const supabase = createClient();

const upload: Uploader = async (file, onProgress) => {
  const path = `${crypto.randomUUID()}-${file.name}`;
  const { error } = await supabase.storage.from("uploads").upload(path, file);
  if (error) throw new Error(error.message); // shows on the file row, with a retry button
  onProgress(100);
};

export default function UploadPage() {
  return <UploadDropzone upload={upload} accept="image/*,.pdf" maxSize={10 * 1024 * 1024} />;
}

lib/supabase/client.ts

import { createBrowserClient } from "@supabase/ssr";

export function createClient() {
  return createBrowserClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!);
}

Good to know

  • supabase-js upload doesn't report progress, so the bar goes from 0 to 100 when the file finishes. For a real bar on big files, use Supabase's resumable (TUS) uploads inside the same upload function.
  • Throw an Error inside upload and the dropzone shows its message on that file with a retry button.
  • The bucket ('uploads' here) needs a storage policy that lets the signed-in user insert, or Supabase answers with a row-level security error.
  • maxSize and accept are checked in the browser only. Set the same limits on the bucket.

Install

  1. One commandnpx shadcn@latest add https://teodoravadani.github.io/qodesign-free/r/upload-dropzone.json
  2. Or ask your AIPaste PROMPT.md into Cursor, Lovable or v0.

Props

upload
(file, onProgress, signal) → Promise
maxSize
bytes, 50 MB by default
accept
for the file picker, e.g. image/*
onAllDone
every file finished

How qodesign compares

All comparisons, with prices read on each library's own site.

Questions

Is it free?

Yes. MIT licence, installed from the free registry.

Can I upload to S3 or UploadThing instead?

Yes. Only the upload function changes.

Can Cursor or v0 add it for me?

Yes. The folder has a PROMPT.md. Paste it into Cursor, Lovable, v0 or Claude Code.

Does the dropzone work in Next.js?

Yes, as a client component. Keep "use client" at the top of the file that renders it, as in the snippet above. App Router and Pages Router both work.

Supabase Storage upload component for Next.js (free, drag and drop) · qodesign