Skip to main content

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:

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

  1. Always validate files before uploading to prevent abuse
  2. Use unique pathnames to avoid overwriting existing files
  3. Set appropriate access levels (public vs private)
  4. Handle errors gracefully in your UI
  5. Consider file size limits for your use case
  6. Use prefixes to organize files into logical folders

Security Considerations

  • The BLOB_READ_WRITE_TOKEN should 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:

  1. Make sure BLOB_READ_WRITE_TOKEN is set in your .env file
  2. 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.