A plugin to use Bunny Storage and Bunny Stream with Payload CMS. Store and serve your media files using Bunny's CDN.
Built on top of @payloadcms/plugin-cloud-storage
for seamless integration with Payload CMS.
- Features
- Installation
- Quick Start
- Plugin Options
- Storage Regions
- Video Handling
- Admin Thumbnails
- Examples
- Upload files to Bunny Storage
- Handle videos with optional Bunny Stream integration for advanced features (HLS, thumbnails)
- Show thumbnails in admin panel
Requires Payload CMS version 3.0.0 or higher.
npm install @seshuk/payload-storage-bunny
# or
yarn add @seshuk/payload-storage-bunny
# or
pnpm add @seshuk/payload-storage-bunny
import { buildConfig } from 'payload'
import { bunnyStorage } from '@seshuk/payload-storage-bunny'
export default buildConfig({
plugins: [
bunnyStorage({
collections: {
media: true, // Use for 'media' collection
},
options: {
storage: {
apiKey: process.env.BUNNY_STORAGE_API_KEY,
hostname: 'files.example.b-cdn.net', // Your custom domain or Bunny hostname
zoneName: 'your-storage-zone',
},
},
}),
],
})
Note: When you use this plugin,
disableLocalStorage
will be automatically set totrue
for each collection. This means files won't be stored locally.
type BunnyAdapterOptions = {
/**
* Admin thumbnail configuration
* - When set to `true`, uses default behavior
* - When object provided, allows customizing thumbnail behavior
*/
adminThumbnail?:
| {
/** Append timestamp for cache busting */
appendTimestamp?: boolean
/** Custom query parameters (can be used with Bunny Optimizer or for other needs) */
queryParams?: Record<string, string>
}
| boolean
/**
* Bunny Storage settings (required)
*/
storage: {
/** Your Storage API key */
apiKey: string
/** Custom domain or Bunny CDN hostname (e.g., 'files.example.b-cdn.net') */
hostname: string
/** Where to store files (optional) */
region?: 'br' | 'jh' | 'la' | 'ny' | 'se' | 'sg' | 'syd' | 'uk' | string
/** Your storage zone name */
zoneName: string
}
/**
* Bunny Stream settings (optional)
* Add this if you want to handle videos with Bunny Stream
*/
stream?: {
/** Your Stream API key */
apiKey: string
/** Stream service URL */
hostname: string
/** Your library ID */
libraryId: string
/** MP4 video quality for direct access */
mp4FallbackQuality?: '240p' | '360p' | '480p' | '720p'
/** When to take video thumbnail (in seconds) */
thumbnailTime?: number
}
}
You can choose where to store your files. If you don't pick a region, the default storage endpoint will be used.
When setting the region
field, use only the region code (like 'uk' or 'ny'), not the full hostname.
Available regions and their codes:
- Default: leave empty or undefined
uk
- London, UKny
- New York, USla
- Los Angeles, USsg
- Singaporese
- Stockholm, SEbr
- São Paulo, BRjh
- Johannesburg, SAsyd
- Sydney, AU
You can also use a custom region code if needed.
Example:
storage: {
apiKey: process.env.BUNNY_STORAGE_API_KEY,
hostname: 'assets.example.b-cdn.net', // Your Bunny CDN hostname
region: 'ny', // Just the code: 'ny', not 'ny.storage.bunnycdn.com'
zoneName: 'my-zone'
}
By default, video files will be uploaded to Bunny Storage just like any other files. However, if you add stream
settings, videos will be handled by Bunny Stream instead, giving you additional features like adaptive streaming and automatic thumbnails.
If you add stream
settings, the plugin will:
To use MP4 video files directly:
- Turn on MP4 support in your Bunny Stream dashboard
- Set
disablePayloadAccessControl
tofalse
in Payload - Choose quality in
mp4FallbackQuality
Use thumbnailTime
to pick when in the video to take the thumbnail (in seconds).
The plugin can show thumbnails in your admin panel. This is optional and works differently for each file type:
- Videos: Uses Bunny Stream's automatic thumbnails (thumbnail.jpg)
- Images: You can add timestamps to refresh cached images and add any query parameters you need. While this is particularly useful with Bunny Optimizer (for image resizing), you can use any query parameters that suit your needs.
Example setup:
bunnyStorage({
options: {
adminThumbnail: {
appendTimestamp: true, // Add time to refresh thumbnails
queryParams: {
// You can use Bunny Optimizer parameters
width: '300',
height: '300',
// Or any other query parameters you need
quality: '90',
custom: 'value',
},
},
// ... other settings
},
})
import { buildConfig } from 'payload'
import { bunnyStorage } from '@seshuk/payload-storage-bunny'
export default buildConfig({
plugins: [
bunnyStorage({
collections: {
media: true,
},
options: {
storage: {
apiKey: process.env.BUNNY_STORAGE_API_KEY,
hostname: 'storage.example.b-cdn.net',
zoneName: 'my-zone',
},
},
}),
],
})
import { buildConfig } from 'payload'
import { bunnyStorage } from '@seshuk/payload-storage-bunny'
export default buildConfig({
plugins: [
bunnyStorage({
collections: {
media: {
prefix: 'media',
},
},
options: {
storage: {
apiKey: process.env.BUNNY_STORAGE_API_KEY,
hostname: 'storage.example.b-cdn.net',
region: 'ny',
zoneName: 'my-zone',
},
stream: {
apiKey: process.env.BUNNY_STREAM_API_KEY,
hostname: 'stream.example.b-cdn.net',
libraryId: 'lib-123',
mp4FallbackQuality: '720p',
},
},
}),
],
})