Note: When you install a Payload plugin, it pulls in the latest version by default, which might not match your project's existing Payload version. This can cause compatibility issues.
To avoid this, either update all Payload dependencies to the latest version before installing a plugin or manually match the versions of the storage plugins to your existing Payload version.
For this tutorial, we’ll use version 3.11, so when installing storage plugins, we’ll demonstrate how to install a specific version.
Step 1: Create a Vercel Blob Storage
- Log in to Vercel (or create an account at vercel.com)
- In the top navigation bar, scroll over to Storage
- Click Create a Database → Select Blob
- Give it a name (e.g.,
test-storage
) and click Create - Under Quick Start, click on
.env.local
to Copy the Snippet - Paste this token into your project's
.env
file: BLOB_READ_WRITE_TOKEN=your-token-here
Step 2: Install the Vercel Blob Storage Adapter
In your terminal, run: pnpm add @payloadcms/storage-vercel-blob
Step 3: Configure Vercel Blob in Payload
Open payload.config.ts
and add the following:
1import VercelBlobStorage from '@payloadcms/storage-vercel-blob';
11 token: process.env.BLOB_READ_WRITE_TOKEN
Step 4: Match Versions and Install Dependencies
To prevent version mismatches:
- Open
package.json
- Set
@payloadcms/storage-vercel-blob
to 3.11 - Run:
pnpm i
Step 5: Test the Upload
- Start the dev server:
pnpm dev
- Log in to Payload Admin
- Navigate to Media
- Click Create New and upload an image
- Verify the upload by checking Vercel Blob storage
Configuring AWS S3 Adapter (Cloudflare R2) in Payload
Step 1: Set Up Cloudflare R2 Object Storage
- Log in to Cloudflare (cloudflare.com)
- Navigate to R2 Object Storage
- Click Create Bucket
- Name it (e.g.,
test-storage
) and select Automatic Location - Click Create Bucket
Step 2: Copy API Credentials
- Locate the S3 API under Settings and "Bucket Details" in your bucket's dashboard
- Copy this into your
.env
file:
1S3_ENDPOINT=your-cloudflare-endpoint
One thing that's not clear is the region you need to use. For Cloudflare’s R2, you'll use auto
for your region, not what's listed as the location. This isn't true for all S3 stores though, so if you're setting this up with AWS or another S3 storage option, you'll want to see if you can find the region elsewhere.
Note: If you don't have a custom domain set up, I explain in greater detail here how to enable the R2's dev subdomain.
We still need two pieces of information: your access key ID and secret access key.
To find these, you'll return to your R2 dashboard.
- To find your Access Key & Secret:
- Return to your R2 dashboard
- Click the "API" button and then select "Manage API tokens"
- Now click "Create API token"
- Set permissions: Object Read/Write
- Apply it to your
test-storage
bucket - Click "Create API token"
- Copy the Access Key ID and Secret Access Key into your
.env
file
2S3_ACCESS_KEY_ID=your-access-key-id
Step 3: Install the S3 Storage Adapter
pnpm add @payloadcms/storage-s3
Step 4: Configure Cloudflare R2 in Payload
Modify payload.config.ts
:
1import S3Storage from '@payloadcms/storage-s3';
9 bucket: process.env.S3_BUCKET || '',
12 accessKeyId: process.env.S3_ACCESS_KEY_ID || '',
13 secretAccessKey: process.env.S3_SECRET || '',
16 endpoint: process.env.S3_ENDPOINT || '',
Step 5: Match Versions and Install Dependencies
- Open
package.json
- Set
@payloadcms/storage-s3
to 3.11 - Run:
pnpm i
Step 6: Test the Upload
- Restart the dev server:
pnpm dev
- Go to Media
- Upload an image
- Verify the file appears in Cloudflare R2 Storage
Configuring Uploadthing in Payload
Step 1: Set Up Uploadthing
- Sign up at uploadthing.com
- Create a New App (
test-storage
) - Go to API Keys and copy your Uploadthing Token
- Add it to your
.env
: UPLOADTHING_TOKEN=your-token-here
Step 2: Install Uploadthing Storage Adapter
1pnpm add @payloadcms/storage-uploadthing
As we did with the other adapters, ensure you match versions by opening package.json
and setting @payloadcms/storage-uploadthing
to 3.11 and run: pnpm i
.
Step 3: Configure Uploadthing in Payload
Modify payload.config.ts
1import UploadthingStorage from '@payloadcms/storage-uploadthing';
10 token: process.env.UPLOADTHING_TOKEN || '',
Step 4: Test the Upload
- Restart the dev server:
pnpm dev
- Return to Media in the Payload admin panel
- Upload an image
- Verify the file appears in Uploadthing Dashboard
Using more than one storage adapter in Payload
You can use more than one storage adapter in Payload.
For example, you might use UploadThing for documents and R2 for images. To do this, set up separate upload collections—one for each adapter.
- Duplicate the existing
Media.ts
collection and rename it to Documents.ts
. - Update the
slug
in that file to slug: 'documents'
- In that same collection, modify
export const Media:
to export const Documents:
- In your Payload config, import the documents collection and add it to the collections array (i.e.
collections: [Users, Media, Posts, Documents]
) - Run
payload generate:types
to include the new collection. - In your Payload config, change the uploadthingStorage collection designation from
media
to documents
.
Now, files in the documents collection will use UploadThing, while media files can continue using Cloudflare R2 (make sure you enable it!)—each adapter scoped to its own collection.