Cloudinary
Build with Cloudinary for image and video management. Use this skill when the
You are a media specialist who integrates Cloudinary into projects. Cloudinary is a cloud-based media management platform for image and video upload, transformation, optimization, and delivery via CDN. ## Key Points - Always use `f_auto,q_auto` for automatic format and quality optimization - Use `gravity: 'auto'` for AI-based smart cropping - Use upload presets for client-side uploads — restricts what can be uploaded - Use `CldImage` in Next.js — it integrates with next/image optimization - Use folders and tags to organize assets - Set `crop: 'limit'` on upload to cap maximum dimensions - Serving original unoptimized images — always apply `q_auto,f_auto` - Generating transformation URLs client-side with API secret exposed - Not using responsive sizes — serve different sizes for different viewports - Uploading duplicate images — use `overwrite: true` or check `public_id` - Storing Cloudinary URLs in the database — store `public_id` and generate URLs - Not setting upload limits — allow arbitrarily large file uploads ## Quick Example ```bash npm install cloudinary npm install next-cloudinary # For Next.js ```
skilldb get storage-services-skills/CloudinaryFull skill: 206 linesCloudinary Integration
You are a media specialist who integrates Cloudinary into projects. Cloudinary is a cloud-based media management platform for image and video upload, transformation, optimization, and delivery via CDN.
Core Philosophy
URL-based transformations
Cloudinary transforms images and videos through URL parameters — resize, crop, format-convert, add overlays, apply effects — all by modifying the delivery URL. No server-side image processing needed.
Automatic optimization
Cloudinary's f_auto and q_auto parameters automatically deliver the best
format (WebP, AVIF) and quality for each browser. You don't manage format
negotiation — Cloudinary handles it at the CDN edge.
Upload once, transform infinitely
Upload the original asset once. Generate any variation (thumbnail, hero, social card, video preview) on the fly via URL transformations. No need to pre-generate sizes.
Setup
Install
npm install cloudinary
npm install next-cloudinary # For Next.js
Initialize
import { v2 as cloudinary } from 'cloudinary';
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME!,
api_key: process.env.CLOUDINARY_API_KEY!,
api_secret: process.env.CLOUDINARY_API_SECRET!,
});
Key Techniques
Upload
// Server-side upload
const result = await cloudinary.uploader.upload(filePath, {
folder: 'posts',
public_id: 'my-image',
transformation: [{ width: 2000, crop: 'limit' }], // Max 2000px wide on upload
tags: ['blog', 'hero'],
});
// result.secure_url, result.public_id, result.width, result.height
// Upload from buffer
const result = await cloudinary.uploader.upload_stream(
{ folder: 'avatars', public_id: userId },
(error, result) => { /* handle */ }
).end(buffer);
// Upload from URL
const result = await cloudinary.uploader.upload('https://example.com/photo.jpg', {
folder: 'imports',
});
// Signed upload preset (client-side uploads)
const preset = await cloudinary.api.create_upload_preset({
name: 'user_avatars',
folder: 'avatars',
allowed_formats: ['jpg', 'png', 'webp'],
transformation: [{ width: 500, height: 500, crop: 'fill', gravity: 'face' }],
});
URL transformations
// Generate transformation URL
const url = cloudinary.url('posts/hero-image', {
width: 800,
height: 400,
crop: 'fill',
gravity: 'auto', // AI-based smart crop
quality: 'auto', // Automatic quality
fetch_format: 'auto', // WebP/AVIF auto
});
// Thumbnail
const thumb = cloudinary.url('posts/hero-image', {
width: 150,
height: 150,
crop: 'thumb',
gravity: 'face',
});
// Text overlay
const social = cloudinary.url('posts/hero-image', {
transformation: [
{ width: 1200, height: 630, crop: 'fill' },
{ overlay: { text: 'My Blog Post Title', font_family: 'Arial', font_size: 48 },
gravity: 'south', y: 40, color: 'white' },
],
});
// Raw URL pattern
// https://res.cloudinary.com/{cloud}/image/upload/w_800,h_400,c_fill,g_auto,q_auto,f_auto/posts/hero-image
Next.js integration (next-cloudinary)
import { CldImage, CldUploadWidget } from 'next-cloudinary';
// Optimized image component
function HeroImage({ publicId }: { publicId: string }) {
return (
<CldImage
src={publicId}
width={1200}
height={630}
crop="fill"
gravity="auto"
alt="Hero image"
sizes="100vw"
/>
);
}
// Upload widget
function ImageUploader({ onUpload }: { onUpload: (url: string) => void }) {
return (
<CldUploadWidget
uploadPreset="user_avatars"
onSuccess={(result) => {
if (typeof result.info !== 'string') {
onUpload(result.info.secure_url);
}
}}
>
{({ open }) => <button onClick={() => open()}>Upload Image</button>}
</CldUploadWidget>
);
}
Video
// Video transformation
const videoUrl = cloudinary.url('videos/intro', {
resource_type: 'video',
width: 720,
crop: 'scale',
quality: 'auto',
fetch_format: 'auto', // MP4/WebM auto
});
// Video thumbnail
const poster = cloudinary.url('videos/intro', {
resource_type: 'video',
format: 'jpg',
transformation: [{ width: 1280, height: 720, crop: 'fill' }],
});
Delete and manage
// Delete
await cloudinary.uploader.destroy('posts/old-image');
// Rename
await cloudinary.uploader.rename('posts/old-name', 'posts/new-name');
// List resources
const { resources } = await cloudinary.api.resources({
type: 'upload',
prefix: 'posts/',
max_results: 50,
});
Best Practices
- Always use
f_auto,q_autofor automatic format and quality optimization - Use
gravity: 'auto'for AI-based smart cropping - Use upload presets for client-side uploads — restricts what can be uploaded
- Use
CldImagein Next.js — it integrates with next/image optimization - Use folders and tags to organize assets
- Set
crop: 'limit'on upload to cap maximum dimensions
Anti-Patterns
- Serving original unoptimized images — always apply
q_auto,f_auto - Generating transformation URLs client-side with API secret exposed
- Not using responsive sizes — serve different sizes for different viewports
- Uploading duplicate images — use
overwrite: trueor checkpublic_id - Storing Cloudinary URLs in the database — store
public_idand generate URLs - Not setting upload limits — allow arbitrarily large file uploads
Install this skill directly: skilldb add storage-services-skills
Related Skills
AWS S3
Build with AWS S3 for object storage. Use this skill when the project needs to
Backblaze B2
Build with Backblaze B2 for low-cost S3-compatible object storage.
Cloudflare R2
Build with Cloudflare R2 for S3-compatible object storage with zero egress fees.
Imagekit
Build with ImageKit for real-time image optimization and delivery. Use this skill
Tigris
Build with Tigris for globally distributed S3-compatible object storage.
Uploadthing
Build with UploadThing for file uploads in Next.js and React. Use this skill when