Back to Skills

vercel-blob

verified

Integrate Vercel Blob for file uploads and CDN-delivered assets in Next.js. Supports client-side uploads with presigned URLs and multipart transfers for large files. Use when implementing file uploads (images, PDFs, videos) or troubleshooting missing tokens, size limits, client upload failures, token expiration errors, or browser compatibility issues. Prevents 16 documented errors.

View on GitHub

Marketplace

claude-skills

jezweb/claude-skills

Plugin

frontend

Repository

jezweb/claude-skills
211stars

skills/vercel-blob/SKILL.md

Last Verified

January 21, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/jezweb/claude-skills/blob/main/skills/vercel-blob/SKILL.md -a claude-code --skill vercel-blob

Installation paths:

Claude
.claude/skills/vercel-blob/
Powered by add-skill CLI

Instructions

# Vercel Blob

**Last Updated**: 2026-01-21
**Version**: @vercel/blob@2.0.0
**Skill Version**: 2.1.0

---

## Quick Start

```bash
# Create Blob store: Vercel Dashboard → Storage → Blob
vercel env pull .env.local  # Creates BLOB_READ_WRITE_TOKEN
npm install @vercel/blob
```

**Server Upload**:
```typescript
'use server';
import { put } from '@vercel/blob';

export async function uploadFile(formData: FormData) {
  const file = formData.get('file') as File;
  const blob = await put(file.name, file, { access: 'public' });
  return blob.url;
}
```

**CRITICAL**: Never expose `BLOB_READ_WRITE_TOKEN` to client. Use `handleUpload()` for client uploads.

---

## Client Upload (Secure)

**Server Action** (generates presigned token):
```typescript
'use server';
import { handleUpload } from '@vercel/blob/client';

export async function getUploadToken(filename: string) {
  return await handleUpload({
    body: {
      type: 'blob.generate-client-token',
      payload: { pathname: `uploads/${filename}`, access: 'public' }
    },
    request: new Request('https://dummy'),
    onBeforeGenerateToken: async (pathname) => ({
      allowedContentTypes: ['image/jpeg', 'image/png'],
      maximumSizeInBytes: 5 * 1024 * 1024
    })
  });
}
```

**Client Component**:
```typescript
'use client';
import { upload } from '@vercel/blob/client';

const tokenResponse = await getUploadToken(file.name);
const blob = await upload(file.name, file, {
  access: 'public',
  handleUploadUrl: tokenResponse.url
});
```

---

## File Management

**List/Delete**:
```typescript
import { list, del } from '@vercel/blob';

// List with pagination
const { blobs, cursor } = await list({ prefix: 'uploads/', cursor });

// Delete
await del(blobUrl);
```

**Multipart (>500MB)**:
```typescript
import { createMultipartUpload, uploadPart, completeMultipartUpload } from '@vercel/blob';

const upload = await createMultipartUpload('large-video.mp4', { access: 'public' });
// Upload chunks in loop...
await completeMultipar

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
12820 chars