Source:
ocean/docs/blob-storage.md| ✏️ Edit on GitHub
Vercel Blob Storage Integration
This project is configured to use Vercel Blob Storage for file uploads and management.
Setup
1. Vercel Dashboard Configuration
Your blob store has been created with the following details:
- Store Name: ocean-blob
- Store ID: store_PGQPVzEM5JuHADbs
- Region: Washington, D.C., USA (IAD1)
- Base URL: https://pgqpvzem5juhadbs.public.blob.vercel-storage.com
2. Environment Variables
When deployed to Vercel, the BLOB_READ_WRITE_TOKEN environment variable is automatically available.
For local development, add the token to your .env file:
BLOB_READ_WRITE_TOKEN=vercel_blob_your_actual_token_here
Usage
Basic File Upload
import { BlobStorageService } from '@/services/blob-storage'
// Upload a file
const file = new File(['Hello World'], 'hello.txt', { type: 'text/plain' })
const result = await BlobStorageService.upload('documents/hello.txt', file)
console.log(result.url) // The public URL of the uploaded file
Upload Form Example
import { useState } from 'react'
import { BlobStorageService } from '@/services/blob-storage'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
export function FileUploadForm() {
const [uploading, setUploading] = useState(false)
const [fileUrl, setFileUrl] = useState<string>()
const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]
if (!file) return
setUploading(true)
try {
// Validate file before upload
BlobStorageService.validateFile(file, {
maxSizeInBytes: 5 * 1024 * 1024, // 5MB
allowedTypes: ['image/jpeg', 'image/png', 'application/pdf'],
})
// Generate a unique pathname
const pathname = BlobStorageService.generatePathname(file.name, 'user-uploads')
// Upload the file
const result = await BlobStorageService.upload(pathname, file, {
access: 'public',
contentType: file.type,
})
setFileUrl(result.url)
console.log('File uploaded:', result)
} catch (error) {
console.error('Upload failed:', error)
} finally {
setUploading(false)
}
}
return (
<div className="space-y-4">
<Input
type="file"
onChange={handleFileUpload}
disabled={uploading}
accept="image/jpeg,image/png,application/pdf"
/>
{uploading && <p>Uploading...</p>}
{fileUrl && (
<div>
<p>File uploaded successfully!</p>
<a href={fileUrl} target="_blank" rel="noopener noreferrer">
View file
</a>
</div>
)}
</div>
)
}
Multiple File Upload
const files = [
{ pathname: 'images/photo1.jpg', data: file1 },
{ pathname: 'images/photo2.jpg', data: file2 },
]
const results = await BlobStorageService.uploadMultiple(files)
List Files
// List all files
const { blobs, hasMore, cursor } = await BlobStorageService.list()
// List files with prefix
const { blobs } = await BlobStorageService.list({
prefix: 'user-uploads/',
limit: 10,
})
Delete Files
// Delete a single file
await BlobStorageService.delete(fileUrl)
// Delete multiple files
await BlobStorageService.deleteMultiple([url1, url2, url3])
Get File Metadata
const metadata = await BlobStorageService.getMetadata(fileUrl)
console.log({
size: metadata.size,
contentType: metadata.contentType,
uploadedAt: metadata.uploadedAt,
})
API Reference
BlobStorageService.upload(pathname, data, options?)
Uploads a file to Vercel Blob Storage.
BlobStorageService.uploadMultiple(files)
Uploads multiple files in parallel.
BlobStorageService.delete(url)
Deletes a file from storage.
BlobStorageService.list(options?)
Lists files in storage with optional filtering.
BlobStorageService.getMetadata(url)
Gets metadata for a file without downloading it.
BlobStorageService.validateFile(file, options)
Validates a file before upload based on size, type, and extension.
BlobStorageService.generatePathname(originalName, folder?)
Generates a unique pathname for a file to avoid collisions.
Best Practices
- Always validate files before uploading to prevent abuse
- Use unique pathnames to avoid overwriting existing files
- Set appropriate access levels (public vs private)
- Handle errors gracefully in your UI
- Consider file size limits for your use case
- Use prefixes to organize files into logical folders
Security Considerations
- The
BLOB_READ_WRITE_TOKENshould never be exposed to the client - Always validate file types and sizes on the server side
- Consider implementing rate limiting for uploads
- Use private access for sensitive files
- Implement proper authentication before allowing uploads
Troubleshooting
Token not found
If you get a "token not found" error in development:
- Make sure
BLOB_READ_WRITE_TOKENis set in your.envfile - Restart your development server after adding the token
CORS errors
Vercel Blob Storage handles CORS automatically for public files. For private files, ensure you're making requests from your verified domain.