Section

Uploading Files to Supabase Storage

Part of The Prince Academy's AI & DX engineering stack.

Follow The Prince Academy Inc.

Now that you've set up your Supabase project and are familiar with the basics of Supabase Storage, let's dive into the exciting part: uploading files! Supabase makes file uploads straightforward, whether you're working with a web application, a mobile app, or even server-side scripts. We'll cover how to upload files using the Supabase JavaScript client library, which is a common scenario for web development.

Before we start uploading, ensure you have your Supabase client initialized in your application. If you haven't done this yet, refer back to the introductory chapters of this book.

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = 'YOUR_SUPABASE_URL'
const supabaseKey = 'YOUR_SUPABASE_ANON_KEY'

const supabase = createClient(supabaseUrl, supabaseKey)

The core function for uploading files in Supabase is upload on the storage client. This function requires a few key pieces of information:

  1. Path: The full path within your storage bucket where you want to store the file. This includes the filename.
  2. File: The actual file content you want to upload. This can be a File object (from an HTML input element), a Blob, or an ArrayBuffer.
  3. Options (optional): This object can include configurations like contentType (useful for browsers to correctly interpret the file type) and upsert (to overwrite existing files if a file with the same path already exists).

Let's look at a common scenario: uploading a file selected by a user via an HTML file input.

const fileInput = document.getElementById('myFileInput');
const file = fileInput.files[0]; // Get the first selected file

async function uploadFile() {
  const filePath = `public/${file.name}`;

  const { data, error } = await supabase.storage
    .from('my-bucket-name') // Replace with your actual bucket name
    .upload(filePath, file, {
      contentType: file.type,
      upsert: true // Optional: overwrite if file exists
    });

  if (error) {
    console.error('Error uploading file:', error);
  } else {
    console.log('File uploaded successfully:', data);
    // You can now use the 'data.path' or 'data.Key' to reference the uploaded file
  }
}

fileInput.addEventListener('change', uploadFile);

In this example:

  • We get the selected file from an HTML input element with the ID myFileInput.
  • We define a filePath. It's good practice to organize your files within your bucket. Here, we're placing it in a public folder.
  • We call supabase.storage.from('my-bucket-name').upload(...).
  • 'my-bucket-name' should be replaced with the name of the storage bucket you created in your Supabase project.
  • We pass the filePath and the file object.
  • We specify contentType: file.type to help the browser and Supabase correctly identify the file's MIME type.
  • upsert: true is used here to replace an existing file if one with the same name already exists at that path. Remove or set to false if you want distinct versions of files.
  • We check for errors and log the success or failure of the upload. The data object returned upon success contains information about the uploaded file, such as its path.

You can also upload files directly from a Blob or ArrayBuffer. This is useful if you've generated file content in memory (e.g., from a canvas or API response).

const blob = new Blob(['This is some text content.'], { type: 'text/plain' });
const filePath = 'my-text-files/my-document.txt';

async function uploadBlob() {
  const { data, error } = await supabase.storage
    .from('my-bucket-name')
    .upload(filePath, blob, {
      contentType: 'text/plain',
      upsert: true
    });

  if (error) {
    console.error('Error uploading blob:', error);
  } else {
    console.log('Blob uploaded successfully:', data);
  }
}

uploadBlob();

When dealing with file uploads, especially in web applications, consider implementing progress indicators for a better user experience. The Supabase client library also provides options for managing upload progress, which we'll touch upon in later sections.

graph TD
    A[User Selects File] --> B{HTML File Input}
    B --> C[JavaScript: Get File Object]
    C --> D[JavaScript: Construct File Path]
    D --> E[Supabase Client: storage.from().upload()]
    E --> F{Supabase Storage Bucket}
    F --> G[File Stored]
    E --> H{Error Handling}
    H -- Success --> I[Log Success/Get File URL]
    H -- Failure --> J[Log Error]