SupaLaunch logo
SUPALAUNCH
ShowcaseDocs
SupaLaunch
HomeDemoDocumentationBlogShowcaseServices and FrameworksTerms of ServicePrivacy policy
Tools
DB Schema GeneratorStartup Idea Generator
Other Projects
Syntha AICreateChatsCron Expression GeneratorAI Prompts Generator
Contacts
Created with ❤️ by Denisdenis@supalaunch.com
  • Showcase
  • Docs
Blog

Supabase storage guide for Next.JS

28 Dec 2024
By Denis
supabasestoragenextjs

Launch your startup with our Supabase + NextJS Starter Kit

SupaLaunch is a SaaS boilerplate built using Supabase and Next.js. It includes authentication, Stripe payments, Postgres database, 20+ TailwindCSS themes, emails, OpenAI API streaming, file storage and more.

  • Save weeks of your time: No need to setup authentication, payments, emails, file storage, etc.
  • Focus on what matters: Spend your time building your product, not boilerplate code.
Get started with SupaLaunch

Supabase storage guide for Next.JS

Want to manage files in your Next.js app securely and efficiently? Supabase Storage is a powerful tool that helps you handle images, videos, and documents with ease. It offers built-in authentication, real-time updates, and scalable architecture, making it a great choice for SaaS projects and startups.

Key Takeaways:

  • What is Supabase Storage? A file management system that integrates seamlessly with Next.js.
  • Why use it? Secure file access, real-time updates, and scalability.
  • Who is it for? SaaS developers, startups, and web developers looking for a Firebase alternative.

Quick Steps to Get Started:

  1. Create a Supabase account and set up a storage bucket.
  2. Configure environment variables in your Next.js project.
  3. Add Supabase client and authentication libraries.
  4. Implement file upload, download, and access control features.

This guide walks you through setting up Supabase Storage, managing files, and securing access with Row-Level Security (RLS). Dive in to learn how to optimize file handling for your Next.js application.

Save IMAGES With Supabase Storage and Next.js

Supabase

https://www.youtube-nocookie.com/embed/87JAdYPC2n0

Setting Up Supabase Storage

Getting Supabase Storage up and running with Next.js involves a few clear, secure steps.

Prerequisites for Setup

Before diving in, make sure you have the following ready:

  • A Supabase account
  • Node.js (latest LTS version)
  • An existing Next.js project
  • A fully functional development environment

Creating a Supabase Storage Bucket

To handle file storage in your Next.js app, you’ll first need to create a storage bucket in Supabase. Here’s how:

  1. Head to the Supabase dashboard and go to the 'Storage' section.
  2. Create a new bucket (for instance, name it 'documents').
  3. Set up the access permissions. By default, buckets are private. To allow anonymous uploads, you can add a Row-Level Security (RLS) policy like this:
CREATE POLICY "Allow uploads" ON storage.objects FOR
INSERT WITH CHECK (
bucket_id = 'documents' AND auth.role() = 'anon'
);

Configuring Environment Variables

Next, add your Supabase credentials to the .env.local file in your project’s root directory:

NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY

After setting up the environment variables, install the required package:

npm install @supabase/auth-helpers-nextjs

Then, create a Supabase client instance in your project:

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

const supabase = createClientComponentClient();

Once this setup is complete, you’re all set to start integrating Supabase Storage into your Next.js application [1][2].

Integrating Supabase Storage with Next.js

With your environment ready, let’s walk through how to integrate Supabase Storage into your Next.js application.

Installing Required Packages

First, install the Supabase JavaScript library:

npm install @supabase/supabase-js

This package streamlines file storage operations and makes client authentication easier [1].

Setting Up the Supabase Client

Create a utility file, utils/supabase.ts, to initialize your Supabase client:

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

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);

export default supabase;

This setup will serve as the foundation for interacting with Supabase Storage [1][2].

Uploading Files to Supabase

Uploading files is a core feature of any storage system. Here’s how you can implement it in your Next.js app:

import supabase from '../utils/supabase';

const FileUploadComponent = () => {
  const handleFileUpload = async (event) => {
    const file = event.target.files[0];
    const { data, error } = await supabase.storage
      .from('documents')
      .upload(`${Date.now()}-${file.name}`, file);

    if (error) {
      console.error('Upload failed:', error.message);
    } else {
      console.log('Uploaded:', data);
    }
  };

  return (
    <input
      type="file"
      onChange={handleFileUpload}
      accept="image/*,application/pdf"
    />
  );
};

This example includes:

  • Error handling to catch and log failed uploads
  • File type restrictions using the accept attribute [1]

To further refine your file uploads, consider adding these checks:

| Type | Purpose | Example Check | |-----------|-------------------------|-----------------------------------------| | File Size | Block oversized uploads | file.size <= 5 * 1024 * 1024 (5MB) | | File Type | Allow specific formats | Match file.type to allowed MIME types | | File Name | Ensure safe file names | Remove special characters and spaces |

With file uploads covered, you’re ready to move on to managing and securing your stored files.

Managing Files in Supabase Storage

These methods are particularly helpful for SaaS applications where secure and efficient file handling is a priority.

Handling File Uploads and Errors

Here's a practical way to manage file uploads while addressing potential errors:

const handleFileUpload = async (file) => {
  try {
    // Check file size before uploading
    if (file.size > 5 * 1024 * 1024) {
      throw new Error('File size exceeds 5MB limit');
    }

    const { data, error } = await supabase.storage
      .from('documents')
      .upload(`${Date.now()}-${file.name}`, file, {
        cacheControl: '3600', // Sets browser cache duration in seconds
        upsert: false // Prevents overwriting existing files
      });

    if (error) throw error;
    return { success: true, data };
  } catch (error) {
    console.error("Error uploading file:", error.message);
    return { success: false, error: error.message };
  }
};

Common upload issues and how to address them:

| Error Type | Solution | | --- | --- | | Size Limit | Validate size before uploading | | Invalid Type | Restrict uploads to specific MIME types | | Auth Error | Ensure the user is logged in | | Duplicate Files | Use upsert: true to overwrite |

Downloading and Using Files

Here’s an example of generating and using a temporary file URL for secure access:

const FileDisplay = ({ filePath }) => {
  const [fileUrl, setFileUrl] = useState(null);

  useEffect(() => {
    const getFileUrl = async () => {
      // Generate a temporary URL for secure access
      const { data, error } = await supabase.storage
        .from('documents')
        .createSignedUrl(filePath, 3600);

      if (data) setFileUrl(data.signedUrl);
    };

    getFileUrl();
  }, [filePath]);

  return fileUrl ? (
    <img src={fileUrl} alt="Stored file" />
  ) : (
    <p>Loading...</p>
  );
};

Securing File Access with RLS

To control access to files, use Row Level Security (RLS) policies:

-- Allow users to access only their own files
CREATE POLICY "Allow individual access"
ON storage.objects FOR SELECT
TO authenticated
USING (auth.uid() = owner_id);

For even more control, implement role-based restrictions in your application:

const downloadFile = async (fileId) => {
  const { data: { role } } = await supabase.auth.getUser();
  // Ensure the user has the required role
  if (role !== 'premium_user') {
    throw new Error('Access denied: Premium subscription required');
  }

  const { data, error } = await supabase.storage
    .from('documents')
    .download(fileId);

  if (error) throw error;
  return data;
};

Best Practices and Advanced Techniques

Optimizing File Storage

Improving file storage can boost the performance of your Next.js app. Use the <Image> component from Next.js for better image delivery, paired with Supabase Storage's caching options for smoother performance.

To manage files effectively, try this caching strategy:

const uploadWithCache = async (file) => {
  const { data, error } = await supabase.storage
    .from('images')
    .upload(`optimized/${file.name}`, file, {
      cacheControl: '31536000',
      contentType: file.type,
      upsert: true
    });
};

Once storage is optimized, you can take it a step further by adding real-time file updates to your app.

Implementing Real-Time Updates

Supabase subscriptions make it easy to monitor storage changes as they happen:

const StorageMonitor = () => {
  useEffect(() => {
    const subscription = supabase
      .channel('storage-changes')
      .on(
        'postgres_changes',
        {
          event: '*',
          schema: 'storage',
          table: 'objects'
        },
        (payload) => {
          updateUIWithNewFile(payload.new);
        }
      )
      .subscribe();

    return () => {
      subscription.unsubscribe();
    };
  }, []);
};

When handling multiple files, process them efficiently in chunks:

const processFileQueue = async (files) => {
  const chunkSize = 2;
  for (let i = 0; i < files.length; i += chunkSize) {
    const chunk = files.slice(i, i + chunkSize);
    await Promise.all(
      chunk.map(file => uploadWithCache(file))
    );
  }
};

For a quicker setup, you can use SupaLaunch, which provides ready-made solutions for real-time file management.

Conclusion and Key Points

Key Steps Recap

Setting up Supabase Storage involves a few essential steps: creating a storage bucket, configuring environment variables, and integrating the Supabase client for secure file management [1]. Adding Row-Level Security (RLS) policies ensures that only approved users can access or interact with stored files, making your application ready for production [1].

Once these steps are in place, Supabase Storage becomes a strong option for managing files in SaaS applications.

Next Steps for Developers

To get the most out of Supabase Storage, consider focusing on a few key areas to enhance your application. These include refining file validation processes, improving storage performance, and using real-time features for dynamic updates - all while maintaining strong security practices.

Here are some practical tips:

  • Use thorough file validation to ensure data integrity.
  • Optimize performance with caching techniques.
  • Take advantage of real-time updates for dynamic functionality.
  • Keep access controls secure and up to date.
  • Regularly monitor and optimize storage usage.

Following these steps will help you create a reliable, scalable file management system for your Next.js application.