Image Upload
How to configure the image upload.
In SuperDir, for image uploads (avatar, project images, project logo), we use uploadthing as the default storage provider. It's free (2G/month) for small projects.
Uploadthing Configuration
If you want to keep using uploadthing as your storage provider, the integration is pretty easy.
Create an account and get an API key
Create an account on uploadthing and get your API key.
Get your endpoint domain
Upload an image in the dashboard, then find the image, click the More button
, Copy File URL
in the format: https://******.ufs.sh/f/******
, replace ******.ufs.sh
with the value of NEXT_PUBLIC_UPLOADTHING_URL
in the next step
Cloudflare R2 Configuration [optional]
Set up Cloudflare R2 for fast, cost-effective file uploads
Why Choose Cloudflare R2?
- 🚀 Global Performance: Cloudflare's edge network for fast uploads worldwide
- 💰 Cost Effective: 10x cheaper than S3 with zero egress fees
- 🔗 S3 Compatible: Works with existing S3 tools and libraries
- 🌍 Built-in CDN: Automatic content distribution via Cloudflare's network
1. Create an R2 Bucket
- Go to Cloudflare Dashboard
- Click "R2 Object Storage" in the sidebar
- Click "Create bucket"
- Choose a unique bucket name (e.g.,
my-app-uploads
) - Select your preferred location (Auto for global performance)
- Click "Create bucket"
2. Configure Public Access (Optional)
- Go to your bucket settings
- Click "Settings" tab
- Under "Public access", click "Allow Access"
3. Custom Domain Setup
Add a CNAME record in your Custom domains
like:
upload.yourdomain.com
4. Generate API Token
- Go to "Manage R2 API tokens"
- Click "Create API token"
- Set permissions:
- Object:Read ✅
- Object:Write ✅
- Bucket:Read ✅
- Choose "Specify bucket" and select your bucket
- Click "Create API token"
- Save your Access Key ID and Secret Access Key
5. Configure CORS (If Using Custom Domain)
Comprehensive CORS Guide: For detailed CORS configuration, testing, and troubleshooting, see the CORS & ACL Configuration Guide.
In your R2 bucket settings, add this CORS policy:
6. Set Environment Variables
Add to your .env
:
🔒 Security Best Practices
- Use scoped API tokens - Only grant permissions to specific buckets
- Enable custom domain - Better security than r2.dev subdomain
- Set up WAF rules - Protect against abuse via Cloudflare dashboard
- Monitor usage - Set up billing alerts for unexpected usage
🆘 Common Issues
- CORS errors? → Check your domain is in AllowedOrigins and verify custom domain setup. For detailed CORS configuration, see the CORS & ACL Configuration Guide.
- Access denied? → Verify API token has Object:Read and Object:Write permissions
- Slow uploads? → Ensure you're using the correct endpoint URL with your account ID
- Custom domain not working? → Verify CNAME record and bucket public access settings
💰 Cost Comparison
Provider | Storage | Egress | Requests |
---|---|---|---|
Cloudflare R2 | $0.015/GB | FREE 🎉 | $0.36/million |
AWS S3 | $0.023/GB | $0.09/GB | $0.40/million |
Savings | 35% less | 100% less | 10% less |
AWS S3 Configuration [optional]
Set up AWS S3 for production file uploads in under 5 minutes
By the end of this guide, you'll have:
- ✅ A secure S3 bucket configured for web uploads
- ✅ IAM user with minimal required permissions
- ✅ CORS configuration for your domain
- ✅ Environment variables ready for production
- ✅ Cost optimization settings enabled
Create AWS Account & S3 Bucket
If you don't have an AWS account, sign up for free - you get 5GB of S3 storage free for 12 months.
- Open S3 Console: Go to S3 Console
- Create Bucket: Click "Create bucket"
- Configure Basic Settings:
Bucket Naming: Use a unique, descriptive name. Bucket names are global across all AWS accounts and cannot be changed later.
- Block Public Access: Keep all "Block public access" settings enabled (this is secure - we'll use presigned URLs)
- Enable Versioning: Recommended for data protection
- Create Bucket: Click "Create bucket"
Configure CORS for Web Access
Comprehensive CORS Guide: For detailed CORS configuration, testing, and troubleshooting, see the CORS & ACL Configuration Guide.
Your web application needs permission to upload files directly to S3.
- Open Your Bucket: Click on your newly created bucket
- Go to Permissions Tab: Click "Permissions"
- Edit CORS Configuration: Scroll to "Cross-origin resource sharing (CORS)" and click "Edit"
- Add CORS Rules:
- Save Changes: Click "Save changes"
Security Note: Only add origins you trust. Wildcards (*
) should never be used in production - they allow any website to upload to your bucket.
Create IAM User with Minimal Permissions
Create a dedicated user for your application with only the permissions it needs.
- Open IAM Console: Go to IAM Console
- Create User:
- Click "Users" → "Create user"
- Username:
your-app-s3-user
- Select "Programmatic access" only
- Create Custom Policy:
- Click "Attach policies directly"
- Click "Create policy"
- Use JSON editor and paste:
- Name the Policy:
YourApp-S3-Upload-Policy
- Attach to User: Go back to user creation and attach your new policy
- Create User: Complete the user creation
Replace Bucket Name: Make sure to replace your-app-uploads-prod
with your actual bucket name in the policy JSON.
Get Access Keys
Your application needs these credentials to generate presigned URLs.
- Select Your User: In IAM Users, click on your newly created user
- Security Credentials Tab: Click "Security credentials"
- Create Access Key:
- Click "Create access key"
- Select "Application running outside AWS"
- Click "Next"
- Copy Credentials:
- Access Key ID: Copy this value
- Secret Access Key: Copy this value (you'll only see it once!)
Security Alert: Never commit these keys to version control or share them publicly. Use environment variables or secure key management services.
Configure Environment Variables
Add your AWS credentials to your .env
file.
DevelopmentProduction
💰 Cost Optimization
Keep your AWS bills low with these optimization tips:
Storage Classes
Set up automatic transitions to save money:
- Go to Your Bucket → Management → Lifecycle rules
- Create Rule:
- Transition to Standard-IA after 30 days
- Transition to Glacier after 90 days
- Delete incomplete multipart uploads after 1 day
Request Optimization
- Use CloudFront: Cache files globally to reduce S3 requests
- Batch Operations: Group multiple operations when possible
- Monitor Usage: Set up billing alerts for unexpected costs
🔒 Security Best Practices
Access Control
Monitoring
- Enable CloudTrail: Track all S3 API calls
- Set Up Alerts: Monitor unusual access patterns
- Regular Audits: Review IAM permissions quarterly