Skip to content
Files SDK
Esc
navigateopen⌘Jpreview
On this page

Vercel Blob

Vercel Blob. Prefers auto-rotating Vercel OIDC (VERCEL_OIDC_TOKEN + BLOB_STORE_ID), falls back to BLOB_READ_WRITE_TOKEN, or pass credentials manually.

Installation

@vercel/blob is an optional peer dependency of files-sdk - install alongside the SDK so the adapter’s imports resolve at runtime.

npm install files-sdk @vercel/blob
pnpm add files-sdk @vercel/blob
yarn add files-sdk @vercel/blob
bun add files-sdk @vercel/blob

Usage

On Vercel, the adapter prefers Vercel’s OIDC authentication when VERCEL_OIDC_TOKEN and BLOB_STORE_ID are present (both are auto-injected when the Blob store is connected to the project). OIDC tokens rotate automatically, so they remove the risk that a long-lived secret leaks from the codebase or environment. Off Vercel - or if OIDC isn’t configured - the adapter falls back to BLOB_READ_WRITE_TOKEN. An explicit token option always wins.

import { Files } from "files-sdk";
import { vercelBlob } from "files-sdk/vercel-blob";

// On Vercel: VERCEL_OIDC_TOKEN + BLOB_STORE_ID are auto-injected when the
// Blob store is connected to the project (OIDC, recommended). Off Vercel,
// or as a fallback, BLOB_READ_WRITE_TOKEN is used.
const files = new Files({ adapter: vercelBlob() });

Pass oidcToken and storeId directly for runtimes that don’t expose process.env (Vite, etc.), or to bypass env detection entirely:

// Frameworks that don't load .env.local into process.env (Vite, etc.)
// need OIDC credentials passed explicitly.
const files = new Files({
  adapter: vercelBlob({
    oidcToken: loadOidcToken(),
    storeId: loadStoreId(),
  }),
});

downloadTimeoutMs bounds the public-URL fetches issued by download() and the lazy bodies returned from head()/list(). Defaults to 5 minutes; pass 0 to disable. A hung CDN response would otherwise leak a fetch that never resolves.

access selects public or private blobs and is fixed at construction. Default "public" matches the existing behavior. With access: "private", uploads use Vercel’s private mode and reads route through blob.get() with whichever credentials the adapter resolved (OIDC or read-write token) instead of a public URL fetch - there is no permanent public URL for private blobs, so url() throws. Need both? Use two adapters.

Options

Could not generate a type table for VercelBlobAdapterOptions: Cannot read properties of undefined (reading 'ESNext')

Limitations

User metadata isn’t supported by the underlying API, so passing a non-empty metadata throws rather than silently dropping it. cacheControl is supported (it maps to the blob’s cacheControlMaxAge).

Compatibility

Public access

Method Status Notes
upload
download
delete
list
search
head
exists
copy
url ⚠️ Returns the permanent CDN URL. expiresIn is silently ignored (no signing primitive); responseContentDisposition throws (no Content-Disposition override available). Use a different provider for buckets with untrusted user-uploaded content.
signedUploadUrl No presigned upload primitive. Use handleUpload() from @vercel/blob/client for browser uploads.

Private access

Method Status Notes
upload
download
delete
list
head
exists
copy
url No URL primitive for private blobs - the underlying SDK requires an authenticated blob.get() call with the token. Use download() instead, or instantiate a second public-access adapter.
signedUploadUrl No presigned upload primitive. Use handleUpload() from @vercel/blob/client for browser uploads.

Was this page helpful?