Receber por email
← Voltar para o catálogo

vercel-blob

Vercel Blob object storage with CDN for Next.js. Use for file uploads (images, PDFs, videos), presigned URLs, user-generated content, file management, or encountering BLOB_READ_WRITE_TOKEN errors, file size limits, client upload token errors.

178estrelas
Atualizado há 5 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add secondsky/claude-skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/vercel-blob-secondsky/svg)](https://www.skillteca.com.br/skills/vercel-blob-secondsky)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Vercel Blob (Object Storage)

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

Quick Start (3 Minutes)

1. Create & Configure

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

Creates: BLOB_READ_WRITE_TOKEN

2. Install

bun add @vercel/blob

3. Upload File (Server Action)

'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',
    contentType: file.type
  });

  return blob.url;
}

4. Basic Operations

import { put, del, list } from '@vercel/blob';

// Upload
const blob = await put('path/file.jpg', file, { access: 'public' });

// Delete
await del(blob.url);

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

Critical Rules

Always Do

| Rule | Why | |------|-----| | Use client upload tokens for client-side uploads | Never expose BLOB_READ_WRITE_TOKEN to client | | Set contentType explicitly | Correct browser handling for PDFs, videos | | Use access: 'public' for CDN caching | Private files bypass CDN | | Validate file type and size before upload | Prevent invalid uploads | | Use pathname organization | avatars/, uploads/, documents/ | | Delete old files when replacing | Manage storage costs |

Never Do

| Rule | Why | |------|-----| | Expose BLOB_READ_WRITE_TOKEN to client | Security vulnerability | | Upload files >500MB without multipart | Use createMultipartUpload API | | Use generic filenames | Use ${Date.now()}-${name} or addRandomSuffix: true | | Skip file validation | Always validate type/size | | Store sensitive data unencrypted | Encrypt before upload | | Forget to handle pagination | list() returns max 1000 files |

Known Issues Prevention

This skill prevents 10 documented issues:

| # | Error | Quick Fix | |---|-------|-----------| | 1 | BLOB_READ_WRITE_TOKEN not defined | Run vercel env pull .env.local | | 2 | Client token exposed | Use handleUpload() for client uploads | | 3 | File size exceeded (500MB) | Use multipart upload API | | 4 | Wrong content-type | Set contentType: file.type | | 5 | No CDN caching | Use access: 'public' | | 6 | Missing files in list | Use cursor pagination | | 7 | Delete fails silently | Use exact URL from put() | | 8 | Upload timeout | Use client-side upload for large files | | 9 | Filename collisions | Add timestamp or addRandomSuffix: true | | 10 | State not updated | Use onUploadCompleted callback |

See: references/known-issues.md for complete solutions with code examples.

Common Patterns Summary

| Pattern | Use Case | Key API | |---------|----------|---------| | Avatar Upload | User profile images | put, del | | Protected Upload | Private documents | put with access: 'private' | | Image Gallery | List & paginate | list with cursor | | Client Upload | Large files, progress | upload, handleUpload | | Multipart Upload | Files >500MB | createMultipartUpload, uploadPart | | Batch Operations | Multiple files | Promise.all, del([...]) | | Image Processing | Optimize before upload | sharp + put |

See: references/common-patterns.md for complete implementations.

Client-Side Upload (Essential Pattern)

Server Action (Token Generation):

'use server';

import { handleUpload, type HandleUploadBody } from '@vercel/blob/client';

export async function generateUploadToken(body: HandleUploadBody) {
  return await handleUpload({
    body,
    request: new Request('https://dummy'),
    onBeforeGenerateToken: async (pathname) => ({
      allowedContentTypes: ['image/jpeg', 'image/png', 'image/webp'],
      maximumSizeInBytes: 5 * 1024 * 1024
    }),
    onUploadCompleted: async ({ blob }) => {
      // Save to database
      await db.insert(uploads).values({ url: blob.url, pathname: blob.pathname });
    }
  });
}

Client Component:

'use client';

import { upload } from '@vercel/blob/client';

const blob = await upload(file.name, file, {
  access: 'public',
  handleUploadUrl: '/api/upload'
});

Configuration

.env.local

# Created by: vercel env pull .env.local
BLOB_READ_WRITE_TOKEN="vercel_blob_rw_xxxxx"

.gitignore

.env.local
.env*.local

When to Load References

| Reference | Load When... | |-----------|--------------| | references/known-issues.md | Debugging upload errors, token issues, or CDN caching problems | | references/common-patterns.md | Implementing avatar uploads, galleries, client uploads, or multipart uploads |

Dependencies

{
  "dependencies": {
    "@vercel/blob": "^2.0.0"
  }
}

Free Tier Limits: 100GB bandwidth/month, 500MB max file size

Official Documentation

  • Vercel Blob: https://vercel.com/docs/storage/vercel-blob
  • Client Upload: https://vercel.com/docs/storage/vercel-blob/client-upload
  • SDK Reference: https://vercel.com/docs/storage/vercel-blob/using-blob-sdk
  • GitHub: https://github.com/vercel/storage

Troubleshooting

| Problem | Solution | |---------|----------| | BLOB_READ_WRITE_TOKEN not defined | Run vercel env pull .env.local | | File size exceeded (>500MB) | Use multipart upload API | | Client upload fails | Use handleUpload() server-side | | Files not deleting | Use exact URL from put() response |

Token Savings: ~60% (patterns extracted to references) Error Prevention: 100% (all 10 documented issues) Ready for production!

Compartilhar X LinkedIn