Source:
ocean/docs/adr/0005-use-vercel-blob-storage-for-public-assets.md| ✏️ Edit on GitHub
ADR-0001: Use Vercel Blob Storage for Public Assets
Status
Accepted
Context
Our application serves various static assets including:
- Cover images (JPEG format, ~100-500KB each)
- Logo files (SVG format)
- Logomark variations (SVG format)
These assets were previously served from the /public directory, which presented several challenges:
- Performance: Assets served from the application server instead of a CDN
- Git repository size: Binary files increase repository size and clone times
- Build size: Static assets included in the application bundle
- Caching: Limited control over asset caching and invalidation
- Global distribution: No automatic geographic distribution of assets
Decision
We will use Vercel Blob Storage to host all public assets except for critical files needed for PWA functionality and SEO (favicon, manifest.json, robots.txt).
Implementation Details
-
Asset Upload Process:
- Created a CLI script (
scripts/upload-assets-to-blob.mjs) that uploads assets from specific public folders - Script checks for existing files to avoid duplicate uploads
- Preserves folder structure in blob storage
- Created a CLI script (
-
Asset Service:
- Created
asset-service.tsthat provides a clean API for getting asset URLs - Uses local paths in development, blob URLs in production
- Components use
getAssetUrl()function for transparent asset resolution
- Created
-
Configured Assets:
/public/Cover Image/- Page cover images/public/Logomark/- Logo mark variations/public/Primary Logo/- Full logo variations
-
Local-Only Assets (for performance/PWA requirements):
favicon.icologo192.pnglogo512.pngmanifest.jsonrobots.txt
Consequences
Positive
-
Performance Improvements:
- Assets served from Vercel's global CDN
- Automatic geographic distribution
- Optimized caching headers
- Reduced server load
-
Development Experience:
- Smaller Git repository size
- Faster clone/pull operations
- Assets still work locally without configuration
-
Cost Efficiency:
- Reduced bandwidth costs on origin server
- Pay-per-use model for blob storage
- No need for separate CDN service
-
Scalability:
- Unlimited storage capacity
- No impact on build size
- Easy to add new assets
Negative
-
Deployment Complexity:
- Additional step in deployment process
- Need to manage
BLOB_READ_WRITE_TOKEN - Assets must be uploaded before deployment
-
Vendor Lock-in:
- Tied to Vercel's blob storage service
- Migration would require updating all asset URLs
-
Local Development:
- Developers need access to blob token for uploading
- Internet connection required to upload new assets
Mitigation Strategies
-
Automated Deployment:
- Added
build:with-assetsscript for CI/CD - Environment variables pulled via Vercel CLI
- Added
-
Fallback Support:
- Asset service falls back to local paths if blob URL not available
- Development mode always uses local assets
-
Documentation:
- Clear documentation for asset management
- Instructions for local development setup
Alternatives Considered
-
Keep assets in public folder:
- Pros: Simple, no external dependencies
- Cons: Poor performance, large repository
-
Use external CDN (Cloudflare, AWS CloudFront):
- Pros: More control, vendor independence
- Cons: Additional service to manage, more complex setup
-
Use Vercel Image Optimization API:
- Pros: Automatic optimization
- Cons: Only for images, runtime processing cost
-
Git LFS (Large File Storage):
- Pros: Keeps files in Git workflow
- Cons: Still impacts clone time, no CDN benefits
References
Date
2024-12-28
Authors
- Development Team (via Claude)
- Reviewed by: [Pending]