
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
payloadcms-plugin-cloudflare-stream
Advanced tools
A Cloudflare Stream plugin for PayloadCMS with client upload support
A powerful plugin that integrates Cloudflare Stream video services with PayloadCMS, providing seamless video uploads, management, and playback capabilities.
npm install payloadcms-plugin-cloudflare-stream
# or
yarn add payloadcms-plugin-cloudflare-stream
# or
pnpm add payloadcms-plugin-cloudflare-stream
Add the plugin to your Payload configuration:
import { buildConfig } from 'payload/config'
import { cloudflareStreamPlugin } from 'payloadcms-plugin-cloudflare-stream'
export default buildConfig({
// Your existing Payload config...
plugins: [
cloudflareStreamPlugin({
accountId: process.env.CLOUDFLARE_ACCOUNT_ID, // Your Cloudflare account ID
apiToken: process.env.CLOUDFLARE_API_TOKEN, // Your Cloudflare API token
streamDomain: process.env.CLOUDFLARE_STREAM_DOMAIN, // e.g., 'https://customer-domain.cloudflarestream.com'
collections: {
'media': true, // Enable for media collection
}
}),
// Other plugins...
],
})
The plugin accepts a configuration object with the following options:
type CloudflareStreamPluginConfig = {
/**
* Collections to apply Cloudflare Stream to
*/
collections: Partial<Record<UploadCollectionSlug, Omit<CollectionOptions, 'adapter'> | true>>
/**
* Cloudflare Account ID
* Can be read from env var - CLOUDFLARE_ACCOUNT_ID
*/
accountId?: string
/**
* Cloudflare API Token
* Can be read from env var - CLOUDFLARE_API_TOKEN
*/
apiToken?: string
/**
* Cloudflare Stream domain
* Used to generate video viewing URLs
* Example: https://customer-domain.cloudflarestream.com
*/
streamDomain?: string
/**
* Enable debug logging
* @default false
*/
debug?: boolean
/**
* Whether the plugin is enabled
* @default true
*/
enabled?: boolean
/**
* Client uploads configuration
*/
clientUploads?: ClientUploadsConfig
/**
* Callback function after video upload
*/
afterUpload?: CloudflareStreamPluginOptions['afterUpload']
/**
* Callback function before video deletion
*/
beforeDelete?: CloudflareStreamPluginOptions['beforeDelete']
/**
* Custom video processing options
*/
videoOptions?: CloudflareStreamPluginOptions['videoOptions']
/**
* Enable client uploads feature
* @default false
*/
enableClientUploads?: boolean
/**
* Client-side upload lifecycle callbacks
*/
clientCallbacks?: ClientUploadCallbacks
/**
* Disable local storage
* @default true
*/
disableLocalStorage?: boolean
}
Enable direct browser-to-Cloudflare uploads for better performance:
cloudflareStreamPlugin({
// Basic config...
enableClientUploads: true,
clientUploads: {
// Optional access control
access: ({ req }) => true, // Control who can generate upload URLs
},
})
### Client Upload Callbacks
Hook into the browser upload lifecycle (requires `enableClientUploads: true`):
```typescript
cloudflareStreamPlugin({
// Basic config...
enableClientUploads: true,
clientCallbacks: {
onProgress: ({ percentage, file }) => {
toast.loading(`正在上传 ${file.name} (${percentage.toFixed(1)}%)`)
},
onSuccess: ({ streamId, uploadType }) => {
toast.success(`视频 ${streamId} 上传完成,方式:${uploadType}`)
},
onError: ({ error, stage }) => {
toast.error(`上传失败(阶段:${stage}):${error.message}`)
},
},
})
The callbacks receive the following payloads:
onProgress: { collectionSlug, file, uploadType, bytesUploaded, bytesTotal, percentage }onSuccess: { collectionSlug, file, uploadType, streamId }onError: { collectionSlug, file, uploadType, stage: 'generate-upload-url' | 'upload', error }
### Video Options
Configure video processing options:
```typescript
cloudflareStreamPlugin({
// Basic config...
videoOptions: {
requireSignedURLs: false, // Whether videos require signed URLs
maxDurationSeconds: 3600, // Max video duration (1 hour)
allowDownload: true, // Allow users to download videos
watermark: {
// Watermark configuration
uid: 'your-watermark-id',
size: 0.1,
position: 'upperRight',
},
}
})
Add custom logic after upload or before deletion:
cloudflareStreamPlugin({
// Basic config...
afterUpload: async ({ streamId, streamUrl, collection, data, file, req }) => {
// Your custom code after upload completes
console.log(`Video ${streamId} uploaded successfully to ${streamUrl}`)
},
beforeDelete: async ({ streamId, collection, doc, req }) => {
// Your custom code before video deletion
console.log(`About to delete video ${streamId}`)
}
})
The plugin automatically polls Cloudflare's API to monitor video processing status. When a video is uploaded, it initially has a processing status. The plugin then polls the API every 5 seconds (up to 20 attempts) until the status changes to either ready or error.
Once the status changes, the plugin automatically updates the document with:
This happens in the background without requiring manual intervention.
Videos are stored in the cloudflareStream field of your documents:
{
"id": "1234567890",
"cloudflareStream": {
"streamId": "cf-stream-id",
"streamUrl": "https://customer-domain.cloudflarestream.com/cf-stream-id/watch",
"status": "ready", // 'processing', 'ready', or 'error'
"uploadedAt": "2023-06-15T12:34:56.789Z",
"size": 12345678,
"duration": 120.5, // in seconds
"thumbnailUrl": "https://customer-domain.cloudflarestream.com/cf-stream-id/thumbnails/thumb.jpg"
}
}
MIT © [Your Organization]
FAQs
A Cloudflare Stream plugin for PayloadCMS with client upload support
We found that payloadcms-plugin-cloudflare-stream demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.