Uploading files to Supabase storage with Next.js

Learn how to integrate Next.js with Supabase Storage to effortlessly upload files.

We'll create a form and upload a file into Supabase Storage.

Install the Supabase Next.js auth helper library into your Next.js project.

npm install @supabase/auth-helpers-nextjs

Add your Supabase credentials to a .env.local file.

NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY

Make sure you create a storage bucket called documents in your Supabase storage.

By default storage buckets are private, so you'll need to add proper RLS policies to allow your users to upload files.

Add a policy definition to allow anon users to upload files to the documents bucket.

CREATE POLICY "Allow uploads" ON storage.objects FOR
  INSERT WITH CHECK (
    bucket_id = 'documents' AND auth.role() = 'anon'
  );

If you want to allow authenticated users to upload files, you can add the following policy definition.

CREATE POLICY "Allow authenticated uploads" ON storage.objects FOR
  INSERT WITH CHECK (
    bucket_id = 'documents' AND auth.role() = 'authenticated'
  );

Let's create a new route /profile and add a form with a file input.

Create a form with a file input and handle the onChange event to upload the file to Supabase Storage.

We use the createClientComponentClient function from the @supabase/auth-helpers-nextjs library to create a Supabase client instance.

import { createClientComponentClient } from '@supabase/auth-helpers-nextjs';

export default function Profile() {
  const supabase = createClientComponentClient();

  // Handle file upload event
  const uploadFile = async (event) => {
    const file = event.target.files[0];
    const bucket = "documents"

    // Call Storage API to upload file
    const { data, error } = await supabase.storage
      .from(bucket)
      .upload(file.name, file);

    // Handle error if upload failed
    if(error) {
      alert('Error uploading file.');
      return;
    }

    alert('File uploaded successfully!');
  };

  return (
    <div>
      <h1>Upload Profile Photo</h1>
      <input type="file" onChange={uploadFile} />
    </div>
  );
}