Skip to main content

Payload Cloudinary

Seamlessly integrate Cloudinary storage with Payload CMS. Enhanced support for versioning, custom fields, public ID control, and advanced PDF handling.

Quick Start

1

Install the plugin

Install payload-cloudinary using your preferred package manager:
npm install payload-cloudinary
# or
yarn add payload-cloudinary
# or
pnpm add payload-cloudinary
# or
bun add payload-cloudinary
2

Configure your Payload setup

Add the plugin to your Payload configuration with your Cloudinary credentials:
import { buildConfig } from 'payload/config';
import { cloudinaryStorage } from 'payload-cloudinary';

export default buildConfig({
  // ... your payload config
  plugins: [
    cloudinaryStorage({
      config: {
        cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
        api_key: process.env.CLOUDINARY_API_KEY,
        api_secret: process.env.CLOUDINARY_API_SECRET
      },
      collections: {
        'media': true, // Enable for media collection
      },
      folder: 'payload-media', // Optional folder name
    })
  ]
});
3

Start uploading to Cloudinary

Your media files are now automatically stored in Cloudinary. Access Cloudinary metadata in your documents:
const doc = await payload.findByID({
  collection: 'media',
  id: 'your-doc-id',
});

// Access Cloudinary metadata
const { public_id, secure_url, format } = doc.cloudinary;
console.log(`File URL: ${secure_url}`);

Features

Cloudinary Integration

Seamless integration with Cloudinary for robust cloud storage. Automatic file uploads, deletions, and URL generation.

Versioning Support

Advanced versioning with history tracking. Keep track of file changes with automatic CDN invalidation support.

PDF Support

Enhanced PDF handling with automatic page count detection, thumbnail generation, and page selection.

Custom Fields

Add custom fields to your media collections. Support for alt text, captions, tags, and any custom metadata.

Public ID Control

Customize how Cloudinary public IDs are generated. Use filenames, add unique suffixes, or create custom generators.

Dynamic Folders

Support for both Fixed and Dynamic Folder Modes. Organize assets with customizable folder structures.

Key Highlights

Advanced Versioning

Enable versioning to track file changes and maintain history:
cloudinaryStorage({
  versioning: {
    enabled: true,
    autoInvalidate: true, // Invalidate old versions in CDN
    storeHistory: true,   // Store version history in database
  },
})
Access version history in your documents:
// Access all versions
doc.versions?.forEach(version => {
  console.log(`Version ${version.version} created at ${version.created_at}`);
  console.log(`URL: ${version.secure_url}`);
});

Custom Public IDs

Control how Cloudinary generates public IDs for better media organization:
cloudinaryStorage({
  publicID: {
    enabled: true,
    useFilename: true,
    uniqueFilename: true,
    // Custom generator function
    generatePublicID: (filename, prefix, folder) => {
      const sanitizedName = filename
        .toLowerCase()
        .replace(/\.[^/.]+$/, "")
        .replace(/[^a-z0-9]/g, '-');
      
      const timestamp = new Date().toISOString()
        .replace(/[^0-9]/g, '').slice(0, 14);
      
      return `${folder}/${sanitizedName}_${timestamp}`;
    },
  },
})

PDF Features

Automatic PDF page count, thumbnail generation, and page selection:
const PDFViewer = ({ media }) => {
  const { public_id, pages, selected_page } = media.cloudinary;
  const cloudName = process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME;
  const page = selected_page || 1;

  return (
    <div>
      <img
        src={`https://res.cloudinary.com/${cloudName}/image/upload/pg_${page},w_300,h_400,c_fill,q_auto,f_jpg/${public_id}.pdf`}
        alt={`PDF Page ${page}`}
      />
      <p>Page {page} of {pages}</p>
    </div>
  );
};

Custom Fields

Add custom fields to your media collections:
cloudinaryStorage({
  customFields: [
    {
      name: 'alt',
      type: 'text',
      label: 'Alt Text',
      admin: {
        description: 'Alternative text for accessibility',
      },
    },
    {
      name: 'caption',
      type: 'text',
      label: 'Caption',
    },
    {
      name: 'tags',
      type: 'array',
      label: 'Tags',
      fields: [
        {
          name: 'tag',
          type: 'text',
          required: true,
        },
      ],
    },
  ],
})

Documentation

Installation & Setup

Get started with installation instructions and environment setup

Configuration Guide

Learn about basic and advanced configuration options

API Reference

Complete API documentation for all plugin options

Frontend Integration

Learn how to use Cloudinary URLs in your frontend

What’s Included

The plugin automatically adds Cloudinary metadata to your media documents:
{
  // Standard Payload fields
  id: string;
  filename: string;
  mimeType: string;
  filesize: number;
  
  // Cloudinary metadata
  cloudinary: {
    public_id: string;
    resource_type: string;
    format: string;
    secure_url: string;
    bytes: number;
    created_at: string;
    version: string;
    version_id: string;
    width?: number;
    height?: number;
    
    // PDF-specific (if applicable)
    pages?: number;
    selected_page?: number;
    thumbnail_url?: string;
  };
  
  // Version history (if enabled)
  versions?: Array<{
    version: string;
    version_id: string;
    created_at: string;
    secure_url: string;
  }>;
}

Need Help?

GitHub Issues

Report bugs or request features

Contact

Get in touch with the author

Build docs developers (and LLMs) love