Skip to main content

Overview

JOIP Web Application uses Supabase Storage for all file uploads, including user media, session thumbnails, community content, and manual session images. This guide covers complete setup, bucket configuration, access policies, and troubleshooting.

Why Supabase Storage?

Supabase Storage is the primary file storage solution for JOIP because:
  • CDN Distribution: Global content delivery network for fast access
  • Automatic Scaling: No file count or bucket limits
  • S3-Compatible API: Standard object storage interface
  • Built-in Image Optimization: Automatic resizing and transformations
  • Public/Private Buckets: Flexible access control
  • Generous Free Tier: 1 GB storage, 2 GB bandwidth per month
  • Direct Integration: Works seamlessly with JOIP’s architecture

Prerequisites

  • Supabase account (free or paid)
  • Basic understanding of object storage concepts
  • Access to Replit Secrets or environment variables

Supabase Project Setup

1

Create Supabase Account

  1. Visit supabase.com
  2. Click “Start your project”
  3. Sign up with GitHub/Google/email
  4. Verify your email address
2

Create New Project

  1. Click “New Project” in Supabase dashboard
  2. Configure your project:
    • Organization: Select or create organization
    • Project Name: joip-production (or your preferred name)
    • Database Password: Generate strong password (save this!)
    • Region: Choose closest to your users (e.g., US East)
    • Pricing Plan: Free (upgrade later as needed)
  3. Click “Create new project”
  4. Wait 2-3 minutes for provisioning
3

Retrieve API Credentials

After project creation:
  1. Navigate to SettingsAPI
  2. Copy the following values:
    • Project URL: https://xyzabcdefg123456.supabase.co
    • anon public key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    • service_role secret key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Keep service_role key secret! It has full access to your project. Never expose in client code.
4

Configure Environment Variables

Add credentials to Replit Secrets:

Storage Bucket Configuration

JOIP uses two primary storage buckets:

1. user-media Bucket

Purpose: Stores user-specific uploads
  • Manual session images
  • Media vault files
  • Session thumbnails
Structure:

2. general Bucket

Purpose: Stores community-shared content
  • Community session snapshots
  • Shared media copies
  • Public resources
Structure:

Create Buckets

1

Access Storage Dashboard

  1. Open your Supabase project
  2. Navigate to Storage in left sidebar
  3. Click “Create a new bucket”
2

Create user-media Bucket

Configure the first bucket:
  • Name: user-media
  • Public bucket: ✓ Enabled (for CDN access)
  • File size limit: 100 MB (or your preference)
  • Allowed MIME types: Leave empty (all types allowed)
Click “Create bucket”
3

Create general Bucket

Repeat for second bucket:
  • Name: general
  • Public bucket: ✓ Enabled
  • File size limit: 100 MB
  • Allowed MIME types: Leave empty
Click “Create bucket”
JOIP automatically creates these buckets on first startup if they don’t exist (server/supabase.ts). Manual creation is recommended for production.

Storage Policies

Supabase uses Row Level Security (RLS) policies for access control. For public buckets, configure policies:

user-media Bucket Policies

general Bucket Policies

JOIP uses the service_role key for server-side storage operations, which bypasses RLS policies. Client policies are for direct Supabase client usage (not currently used in JOIP).

File Upload Implementation

JOIP implements file uploads using in-memory buffers with Multer and Sharp for image processing.

Upload Flow

Server-Side Upload (server/upload.ts)

Upload to Supabase (server/supabase.ts)

File Management Operations

Upload File

Delete File

Delete Folder (Session Cleanup)

Copy File Between Buckets

Storage Diagnostics

JOIP provides a storage status endpoint for troubleshooting:

Check Storage Health

Response:
Error Response (Paused Project):

Common Status Codes

  • STORAGE_CONFIG_ERROR: Missing environment variables
  • STORAGE_UNREACHABLE: Cannot connect to Supabase
  • STORAGE_PREFLIGHT_FAILED: Bucket creation/access failed
  • UPLOAD_FAILED: Test upload failed

Image Optimization

Supabase Storage supports automatic image transformations via URL parameters:

Resize Image

Quality Adjustment

Format Conversion

Combined Transformations

Image transformations are cached at the CDN edge for optimal performance.

Monitoring and Limits

Storage Usage

Monitor storage usage in Supabase dashboard:
  1. Open your project
  2. Navigate to SettingsUsage
  3. View:
    • Total storage used
    • Bandwidth consumed
    • API requests count
    • Active connections

Free Tier Limits

  • Storage: 1 GB
  • Bandwidth: 2 GB/month
  • API requests: Unlimited (rate-limited)
  • File size: 50 MB (configurable up to 5 GB on paid plans)
Exceeding Limits: Projects exceeding free tier limits may be throttled or paused. Upgrade to paid plan for higher limits.
Supabase Pro plan ($25/month) includes:
  • 100 GB storage
  • 200 GB bandwidth
  • No pausing due to inactivity
  • Priority support
  • Increased file size limits (5 GB)

Troubleshooting

Storage Unreachable (503 Errors)

Symptom: Manual session uploads fail with STORAGE_UNREACHABLE Cause: Supabase project is paused (free tier inactivity) Solution:
  1. Log in to Supabase dashboard
  2. Navigate to your project
  3. Click “Resume Project” (green button)
  4. Wait 1-2 minutes for project to wake up
  5. Test with GET /api/storage/status

Missing Buckets

Symptom: Upload fails with “Bucket not found” error Solution:
  1. Check bucket names: user-media and general (case-sensitive)
  2. Manually create buckets in Supabase dashboard
  3. Restart JOIP application to auto-create
  4. Verify bucket creation with storage status endpoint

CORS Errors

Symptom: Browser console shows CORS policy errors Solution:
  1. Ensure buckets are marked as “Public”
  2. Add allowed origins in Supabase AuthenticationURL Configuration:
  3. Clear browser cache and retry

File Size Limit Errors

Symptom: Upload fails with “File too large” error Solution:
  1. Check client-side validation (100 MB default)
  2. Adjust Multer limit in server/upload.ts:
  3. Update Supabase bucket settings (dashboard)
  4. Consider compressing images before upload

Invalid File Type

Symptom: Upload rejected with “Invalid file type” error Solution:
  1. Check allowed MIME types in server/upload.ts
  2. Add additional types if needed:
  3. Restart application

Slow Upload Performance

Symptom: Uploads take unusually long time Solutions:
  1. Check Supabase Region: Use region closest to users
  2. Enable Image Compression: Use Sharp to compress before upload:
  3. Upgrade Supabase Plan: Pro plan offers better performance
  4. Monitor Network: Check for ISP throttling or network issues

Orphaned Files

Symptom: Files remain in storage after deleting database records Prevention:
  • Always delete storage files before database records
  • Use database transactions to ensure atomicity
  • Implement cleanup jobs for orphaned files
Cleanup Script:

Security Best Practices

Storage Security Checklist:
  • ✓ Never expose SUPABASE_SERVICE_KEY in client code
  • ✓ Validate file types and sizes server-side
  • ✓ Sanitize filenames to prevent path traversal
  • ✓ Use user-specific folders for isolation
  • ✓ Implement rate limiting on upload endpoints
  • ✓ Regularly audit storage usage
  • ✓ Enable Supabase project billing alerts
  • ✓ Rotate API keys periodically

Filename Sanitization

Path Validation

Performance Optimization

CDN Caching

Supabase Storage uses Cloudflare CDN with automatic caching:
  • Static Assets: Cached for 1 year
  • Dynamic Content: Respect Cache-Control headers
  • Purging: Automatic on file update/delete

Lazy Loading

Implement lazy loading for images:

Batch Operations

Batch uploads and deletes for better performance:

Next Steps

Deploy on Replit

Deploy your configured storage to Replit

Environment Variables

Complete environment variable reference

Database Setup

Configure PostgreSQL database