Adapters
Supabase Storage
Use Shelf UI components with Supabase Storage for seamless file uploads.
SupabaseStorage
Introduction
The Supabase adapter provides first-class integration with Supabase Storage, making it easy to upload, manage, and serve files directly from your Supabase project.
Installation
pnpm add @supabase/supabase-jsSetup
1. Create Supabase Client
// lib/supabase.ts
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)2. Create Storage Bucket
In your Supabase dashboard:
- Go to Storage
- Create a new bucket (e.g.,
uploads) - Set the bucket policy (public or private)
Storage Policies
Make sure to configure Row Level Security (RLS) policies for your storage bucket to control access.
Usage
Basic Upload
import { Dropzone } from "@/components/ui/dropzone"
import { supabase } from "@/lib/supabase"
import { useState } from "react"
export function SupabaseUpload() {
const [uploading, setUploading] = useState(false)
const handleUpload = async (files: File[]) => {
setUploading(true)
for (const file of files) {
const filePath = `${Date.now()}-${file.name}`
const { data, error } = await supabase.storage
.from('uploads')
.upload(filePath, file)
if (error) {
console.error('Upload error:', error)
} else {
console.log('Uploaded:', data.path)
}
}
setUploading(false)
}
return (
<Dropzone onDrop={handleUpload} disabled={uploading}>
{uploading ? 'Uploading...' : 'Drop files to upload'}
</Dropzone>
)
}Get Public URL
const { data } = supabase.storage
.from('uploads')
.getPublicUrl('file-path.jpg')
console.log(data.publicUrl)Download File
const { data, error } = await supabase.storage
.from('uploads')
.download('file-path.jpg')Delete File
const { error } = await supabase.storage
.from('uploads')
.remove(['file-path.jpg'])Advanced
Upload with Progress
import { UploadProgress } from "@/components/ui/upload-progress"
const { data, error } = await supabase.storage
.from('uploads')
.upload(filePath, file, {
cacheControl: '3600',
upsert: false,
onUploadProgress: (progress) => {
const percent = (progress.loaded / progress.total) * 100
console.log(`Upload ${percent}% complete`)
}
})Image Transformations
Supabase supports on-the-fly image transformations:
const { data } = supabase.storage
.from('uploads')
.getPublicUrl('image.jpg', {
transform: {
width: 500,
height: 500,
resize: 'cover',
quality: 80
}
})Optimized Delivery
Supabase Storage uses Cloudflare CDN for fast, global file delivery.
Environment Variables
Add these to your .env.local:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-keyRelated
- AWS S3 — Amazon S3 integration
- Cloudinary — Cloudinary integration
- Dropzone — Upload component
Last Updated on Jun 22, 2026