vercel-blob — for Claude Code vercel-blob, fde-discovery, community, for Claude Code, ide skills, Creates, ### 2. Install, ### 3. Upload File (Server Action), BLOB_READ_WRITE_TOKEN, access

v1.0.0

关于此技能

适用场景: Ideal for AI agents that need vercel blob (object storage). 本地化技能摘要: vercel-blob helps AI agents handle repository-specific developer workflows with documented implementation details.

功能特性

Vercel Blob (Object Storage)
Status : Production Ready
Last Updated : 2025-10-29
Dependencies : None
Latest Versions : @vercel/blob@2.0.0

# 核心主题

TryTraza TryTraza
[0]
[0]
更新于: 4/15/2026

Killer-Skills Review

Decision support comes first. Repository text comes second.

Reference-Only Page Review Score: 10/11

This page remains useful for teams, but Killer-Skills treats it as reference material instead of a primary organic landing page.

Original recommendation layer Concrete use-case guidance Explicit limitations and caution Quality floor passed for review
Review Score
10/11
Quality Score
52
Canonical Locale
en
Detected Body Locale
en

适用场景: Ideal for AI agents that need vercel blob (object storage). 本地化技能摘要: vercel-blob helps AI agents handle repository-specific developer workflows with documented implementation details.

核心价值

推荐说明: vercel-blob helps agents vercel blob (object storage). vercel-blob helps AI agents handle repository-specific developer workflows with documented implementation details.

适用 Agent 类型

适用场景: Ideal for AI agents that need vercel blob (object storage).

赋予的主要能力 · vercel-blob

适用任务: Applying Vercel Blob (Object Storage)
适用任务: Applying Status : Production Ready
适用任务: Applying Last Updated : 2025-10-29

! 使用限制与门槛

  • 限制说明: Use client upload tokens for direct client uploads (don't expose BLOB READ WRITE TOKEN)
  • 限制说明: throw new Error('Only images allowed');
  • 限制说明: Requires repository-specific context from the skill documentation

Why this page is reference-only

  • - Current locale does not satisfy the locale-governance contract.

Source Boundary

The section below is imported from the upstream repository and should be treated as secondary evidence. Use the Killer-Skills review above as the primary layer for fit, risk, and installation decisions.

评审后的下一步

先决定动作,再继续看上游仓库材料

Killer-Skills 的主价值不应该停在“帮你打开仓库说明”,而是先帮你判断这项技能是否值得安装、是否应该回到可信集合复核,以及是否已经进入工作流落地阶段。

实验室 Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

常见问题与安装步骤

以下问题与步骤与页面结构化数据保持一致,便于搜索引擎理解页面内容。

? FAQ

vercel-blob 是什么?

适用场景: Ideal for AI agents that need vercel blob (object storage). 本地化技能摘要: vercel-blob helps AI agents handle repository-specific developer workflows with documented implementation details.

如何安装 vercel-blob?

运行命令:npx killer-skills add TryTraza/fde-discovery/vercel-blob。支持 Cursor、Windsurf、VS Code、Claude Code 等 19+ IDE/Agent。

vercel-blob 适用于哪些场景?

典型场景包括:适用任务: Applying Vercel Blob (Object Storage)、适用任务: Applying Status : Production Ready、适用任务: Applying Last Updated : 2025-10-29。

vercel-blob 支持哪些 IDE 或 Agent?

该技能兼容 Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer。可使用 Killer-Skills CLI 一条命令通用安装。

vercel-blob 有哪些限制?

限制说明: Use client upload tokens for direct client uploads (don't expose BLOB READ WRITE TOKEN);限制说明: throw new Error('Only images allowed');;限制说明: Requires repository-specific context from the skill documentation。

安装步骤

  1. 1. 打开终端

    在你的项目目录中打开终端或命令行。

  2. 2. 执行安装命令

    运行:npx killer-skills add TryTraza/fde-discovery/vercel-blob。CLI 会自动识别 IDE 或 AI Agent 并完成配置。

  3. 3. 开始使用技能

    vercel-blob 已启用,可立即在当前项目中调用。

! 参考页模式

此页面仍可作为安装与查阅参考,但 Killer-Skills 不再把它视为主要可索引落地页。请优先阅读上方评审结论,再决定是否继续查看上游仓库说明。

Upstream Repository Material

The section below is imported from the upstream repository and should be treated as secondary evidence. Use the Killer-Skills review above as the primary layer for fit, risk, and installation decisions.

Upstream Source

vercel-blob

安装 vercel-blob,这是一款面向AI agent workflows and automation的 AI Agent Skill。查看评审结论、使用场景与安装路径。

SKILL.md
Readonly
Upstream Repository Material
The section below is imported from the upstream repository and should be treated as secondary evidence. Use the Killer-Skills review above as the primary layer for fit, risk, and installation decisions.
Supporting Evidence

Vercel Blob (Object Storage)

Status: Production Ready Last Updated: 2025-10-29 Dependencies: None Latest Versions: @vercel/blob@2.0.0


Quick Start (3 Minutes)

1. Create Blob Store

bash
1# In Vercel dashboard: Storage → Create Database → Blob 2vercel env pull .env.local

Creates: BLOB_READ_WRITE_TOKEN

2. Install

bash
1npm install @vercel/blob

3. Upload File (Server Action)

typescript
1'use server'; 2 3import { put } from '@vercel/blob'; 4 5export async function uploadFile(formData: FormData) { 6 const file = formData.get('file') as File; 7 8 const blob = await put(file.name, file, { 9 access: 'public' // or 'private' 10 }); 11 12 return blob.url; // https://xyz.public.blob.vercel-storage.com/file.jpg 13}

CRITICAL:

  • Use client upload tokens for direct client uploads (don't expose BLOB_READ_WRITE_TOKEN)
  • Set correct access level (public vs private)
  • Files are automatically distributed via CDN

The 5-Step Setup Process

Step 1: Create Blob Store

Vercel Dashboard:

  1. Project → Storage → Create Database → Blob
  2. Copy BLOB_READ_WRITE_TOKEN

Local Development:

bash
1vercel env pull .env.local

Creates .env.local:

bash
1BLOB_READ_WRITE_TOKEN="vercel_blob_rw_xxx"

Key Points:

  • Free tier: 100GB bandwidth/month
  • File size limit: 500MB per file
  • Automatic CDN distribution
  • Public files are cached globally

Step 2: Server-Side Upload

Next.js Server Action:

typescript
1'use server'; 2 3import { put } from '@vercel/blob'; 4 5export async function uploadAvatar(formData: FormData) { 6 const file = formData.get('avatar') as File; 7 8 // Validate file 9 if (!file.type.startsWith('image/')) { 10 throw new Error('Only images allowed'); 11 } 12 13 if (file.size > 5 * 1024 * 1024) { 14 throw new Error('Max file size: 5MB'); 15 } 16 17 // Upload 18 const blob = await put(`avatars/${Date.now()}-${file.name}`, file, { 19 access: 'public', 20 addRandomSuffix: false 21 }); 22 23 return { 24 url: blob.url, 25 pathname: blob.pathname 26 }; 27}

API Route (Edge Runtime):

typescript
1import { put } from '@vercel/blob'; 2 3export const runtime = 'edge'; 4 5export async function POST(request: Request) { 6 const formData = await request.formData(); 7 const file = formData.get('file') as File; 8 9 const blob = await put(file.name, file, { access: 'public' }); 10 11 return Response.json(blob); 12}

Step 3: Client-Side Upload (Presigned URLs)

Create Upload Token (Server Action):

typescript
1'use server'; 2 3import { handleUpload, type HandleUploadBody } from '@vercel/blob/client'; 4 5export async function getUploadToken(filename: string) { 6 const jsonResponse = await handleUpload({ 7 body: { 8 type: 'blob.generate-client-token', 9 payload: { 10 pathname: `uploads/${filename}`, 11 access: 'public', 12 onUploadCompleted: { 13 callbackUrl: `${process.env.NEXT_PUBLIC_URL}/api/upload-complete` 14 } 15 } 16 }, 17 request: new Request('https://dummy'), 18 onBeforeGenerateToken: async (pathname) => { 19 // Optional: validate user permissions 20 return { 21 allowedContentTypes: ['image/jpeg', 'image/png', 'image/webp'], 22 maximumSizeInBytes: 5 * 1024 * 1024 // 5MB 23 }; 24 }, 25 onUploadCompleted: async ({ blob, tokenPayload }) => { 26 console.log('Upload completed:', blob.url); 27 } 28 }); 29 30 return jsonResponse; 31}

Client Upload:

typescript
1'use client'; 2 3import { upload } from '@vercel/blob/client'; 4import { getUploadToken } from './actions'; 5 6export function UploadForm() { 7 async function handleSubmit(e: React.FormEvent<HTMLFormElement>) { 8 e.preventDefault(); 9 const form = e.currentTarget; 10 const file = (form.elements.namedItem('file') as HTMLInputElement).files?.[0]; 11 12 if (!file) return; 13 14 const tokenResponse = await getUploadToken(file.name); 15 16 const blob = await upload(file.name, file, { 17 access: 'public', 18 handleUploadUrl: tokenResponse.url 19 }); 20 21 console.log('Uploaded:', blob.url); 22 } 23 24 return ( 25 <form onSubmit={handleSubmit}> 26 <input type="file" name="file" required /> 27 <button type="submit">Upload</button> 28 </form> 29 ); 30}

Step 4: List, Download, Delete

List Files:

typescript
1import { list } from '@vercel/blob'; 2 3const { blobs } = await list({ 4 prefix: 'avatars/', 5 limit: 100 6}); 7 8// Returns: { url, pathname, size, uploadedAt, ... }[]

List with Pagination:

typescript
1let cursor: string | undefined; 2const allBlobs = []; 3 4do { 5 const { blobs, cursor: nextCursor } = await list({ 6 prefix: 'uploads/', 7 cursor 8 }); 9 allBlobs.push(...blobs); 10 cursor = nextCursor; 11} while (cursor);

Download File:

typescript
1// Files are publicly accessible if access: 'public' 2const url = 'https://xyz.public.blob.vercel-storage.com/file.pdf'; 3const response = await fetch(url); 4const blob = await response.blob();

Delete File:

typescript
1import { del } from '@vercel/blob'; 2 3await del('https://xyz.public.blob.vercel-storage.com/file.jpg'); 4 5// Or delete multiple 6await del([url1, url2, url3]);

Step 5: Streaming & Multipart

Streaming Upload:

typescript
1import { put } from '@vercel/blob'; 2import { createReadStream } from 'fs'; 3 4const stream = createReadStream('./large-file.mp4'); 5 6const blob = await put('videos/large-file.mp4', stream, { 7 access: 'public', 8 contentType: 'video/mp4' 9});

Multipart Upload (Large Files >500MB):

typescript
1import { createMultipartUpload, uploadPart, completeMultipartUpload } from '@vercel/blob'; 2 3// 1. Start multipart upload 4const upload = await createMultipartUpload('large-video.mp4', { 5 access: 'public' 6}); 7 8// 2. Upload parts (chunks) 9const partSize = 100 * 1024 * 1024; // 100MB chunks 10const parts = []; 11 12for (let i = 0; i < totalParts; i++) { 13 const chunk = getChunk(i, partSize); 14 const part = await uploadPart(chunk, { 15 uploadId: upload.uploadId, 16 partNumber: i + 1 17 }); 18 parts.push(part); 19} 20 21// 3. Complete upload 22const blob = await completeMultipartUpload({ 23 uploadId: upload.uploadId, 24 parts 25});

Critical Rules

Always Do

Use client upload tokens for client-side uploads - Never expose BLOB_READ_WRITE_TOKEN to client

Set correct access level - public (CDN) or private (authenticated access)

Validate file types and sizes - Before upload, check MIME type and size

Use pathname organization - avatars/, uploads/, documents/ for structure

Handle upload errors - Network failures, size limits, token expiration

Clean up old files - Delete unused files to manage storage costs

Set content-type explicitly - For correct browser handling (videos, PDFs)

Never Do

Never expose BLOB_READ_WRITE_TOKEN to client - Use handleUpload() for client uploads

Never skip file validation - Always validate type, size, content before upload

Never upload files >500MB without multipart - Use multipart upload for large files

Never use generic filenames - file.jpg collides, use ${timestamp}-${name} or UUID

Never assume uploads succeed - Always handle errors (network, quota, etc.)

Never store sensitive data unencrypted - Encrypt before upload if needed

Never forget to delete temporary files - Old uploads consume quota


Known Issues Prevention

This skill prevents 10 documented issues:

Issue #1: Missing Environment Variable

Error: Error: BLOB_READ_WRITE_TOKEN is not defined Source: https://vercel.com/docs/storage/vercel-blob Why It Happens: Token not set in environment Prevention: Run vercel env pull .env.local and ensure .env.local in .gitignore.

Issue #2: Client Upload Token Exposed

Error: Security vulnerability, unauthorized uploads Source: https://vercel.com/docs/storage/vercel-blob/client-upload Why It Happens: Using BLOB_READ_WRITE_TOKEN directly in client code Prevention: Use handleUpload() to generate client-specific tokens with constraints.

Issue #3: File Size Limit Exceeded

Error: Error: File size exceeds limit (500MB) Source: https://vercel.com/docs/storage/vercel-blob/limits Why It Happens: Uploading file >500MB without multipart upload Prevention: Validate file size before upload, use multipart upload for large files.

Issue #4: Wrong Content-Type

Error: Browser downloads file instead of displaying (e.g., PDF opens as text) Source: Production debugging Why It Happens: Not setting contentType option, Blob guesses incorrectly Prevention: Always set contentType: file.type or explicit MIME type.

Issue #5: Public File Not Cached

Error: Slow file delivery, high egress costs Source: Vercel Blob best practices Why It Happens: Using access: 'private' for files that should be public Prevention: Use access: 'public' for publicly accessible files (CDN caching).

Issue #6: List Pagination Not Handled

Error: Only first 1000 files returned, missing files Source: https://vercel.com/docs/storage/vercel-blob/using-blob-sdk#list Why It Happens: Not iterating with cursor for large file lists Prevention: Use cursor-based pagination in loop until cursor is undefined.

Issue #7: Delete Fails Silently

Error: Files not deleted, storage quota fills up Source: https://github.com/vercel/storage/issues/150 Why It Happens: Using wrong URL format, blob not found Prevention: Use full blob URL from put() response, check deletion result.

Issue #8: Upload Timeout (Large Files)

Error: Error: Request timeout for files >100MB Source: Vercel function timeout limits Why It Happens: Serverless function timeout (10s free tier, 60s pro) Prevention: Use client-side upload with handleUpload() for large files.

Issue #9: Filename Collisions

Error: Files overwritten, data loss Source: Production debugging Why It Happens: Using same filename for multiple uploads Prevention: Add timestamp/UUID: `uploads/${Date.now()}-${file.name}` or addRandomSuffix: true.

Issue #10: Missing Upload Callback

Error: Upload completes but app state not updated Source: https://vercel.com/docs/storage/vercel-blob/client-upload#callback-after-upload Why It Happens: Not implementing onUploadCompleted callback Prevention: Use onUploadCompleted in handleUpload() to update database/state.


Configuration Files Reference

package.json

json
1{ 2 "dependencies": { 3 "@vercel/blob": "^2.0.0" 4 } 5}

.env.local

bash
1BLOB_READ_WRITE_TOKEN="vercel_blob_rw_xxxxx"

Common Patterns

Pattern 1: Avatar Upload

typescript
1'use server'; 2 3import { put, del } from '@vercel/blob'; 4 5export async function updateAvatar(userId: string, formData: FormData) { 6 const file = formData.get('avatar') as File; 7 8 // Validate 9 if (!file.type.startsWith('image/')) { 10 throw new Error('Only images allowed'); 11 } 12 13 // Delete old avatar 14 const user = await db.query.users.findFirst({ where: eq(users.id, userId) }); 15 if (user?.avatarUrl) { 16 await del(user.avatarUrl); 17 } 18 19 // Upload new 20 const blob = await put(`avatars/${userId}.jpg`, file, { 21 access: 'public', 22 contentType: file.type 23 }); 24 25 // Update database 26 await db.update(users).set({ avatarUrl: blob.url }).where(eq(users.id, userId)); 27 28 return blob.url; 29}

Pattern 2: Protected File Upload

typescript
1'use server'; 2 3import { put } from '@vercel/blob'; 4import { auth } from '@/lib/auth'; 5 6export async function uploadDocument(formData: FormData) { 7 const session = await auth(); 8 if (!session) throw new Error('Unauthorized'); 9 10 const file = formData.get('document') as File; 11 12 // Upload as private 13 const blob = await put(`documents/${session.user.id}/${file.name}`, file, { 14 access: 'private' // Requires authentication to access 15 }); 16 17 // Store in database with user reference 18 await db.insert(documents).values({ 19 userId: session.user.id, 20 url: blob.url, 21 filename: file.name, 22 size: file.size 23 }); 24 25 return blob; 26}
typescript
1import { list } from '@vercel/blob'; 2 3export async function getGalleryImages(cursor?: string) { 4 const { blobs, cursor: nextCursor } = await list({ 5 prefix: 'gallery/', 6 limit: 20, 7 cursor 8 }); 9 10 const images = blobs.map(blob => ({ 11 url: blob.url, 12 uploadedAt: blob.uploadedAt, 13 size: blob.size 14 })); 15 16 return { images, nextCursor }; 17}

Dependencies

Required:

  • @vercel/blob@^2.0.0 - Vercel Blob SDK

Optional:

  • sharp@^0.33.0 - Image processing before upload
  • zod@^3.24.0 - File validation schemas

Official Documentation


Package Versions (Verified 2025-10-29)

json
1{ 2 "dependencies": { 3 "@vercel/blob": "^2.0.0" 4 } 5}

Production Example

  • E-commerce: Product images, user uploads (500K+ files)
  • Blog Platform: Featured images, author avatars
  • SaaS: Document uploads, PDF generation, CSV exports
  • Errors: 0 (all 10 known issues prevented)

Troubleshooting

Problem: BLOB_READ_WRITE_TOKEN is not defined

Solution: Run vercel env pull .env.local, ensure .env.local in .gitignore.

Problem: File size exceeded (>500MB)

Solution: Use multipart upload with createMultipartUpload() API.

Problem: Client upload fails with token error

Solution: Ensure using handleUpload() server-side, don't expose read/write token to client.

Problem: Files not deleting

Solution: Use exact URL from put() response, check del() return value.


Complete Setup Checklist

  • Blob store created in Vercel dashboard
  • BLOB_READ_WRITE_TOKEN environment variable set
  • @vercel/blob package installed
  • File validation implemented (type, size)
  • Client upload uses handleUpload() (not direct token)
  • Content-type set for uploads
  • Access level correct (public vs private)
  • Deletion of old files implemented
  • List pagination handles cursor
  • Tested file upload/download/delete locally and in production

Questions? Issues?

  1. Check official docs: https://vercel.com/docs/storage/vercel-blob
  2. Verify environment variables are set
  3. Ensure using client upload tokens for client-side uploads
  4. Monitor storage usage in Vercel dashboard

相关技能

寻找 vercel-blob 的替代方案 (Alternative) 或可搭配使用的同类 community Skill?探索以下相关开源技能。

查看全部

openclaw-release-maintainer

Logo of openclaw
openclaw

Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

333.8k
0
AI

widget-generator

Logo of f
f

Generate customizable widget plugins for the prompts.chat feed system

149.6k
0
AI

flags

Logo of vercel
vercel

The React Framework

138.4k
0
浏览器

pr-review

Logo of pytorch
pytorch

Tensors and Dynamic neural networks in Python with strong GPU acceleration

98.6k
0
开发者工具