Cloudinary OG Images: Generate Social Preview Images with URL Transforms
How to use Cloudinary to generate, resize, overlay text, and serve dynamic og:image social preview images — without any server infrastructure.
Updated March 2026
Why Cloudinary for OG Images?
Cloudinary lets you generate dynamic social preview images entirely through URL parameters — no Lambda functions, no canvas rendering, no server. Resize, crop, add text overlays, and apply brand templates, all by modifying the image URL.
Basic: Resize to OG Image Dimensions
The standard OG image size is 1200×630px at a 1.91:1 ratio:
<!-- Original image URL --> https://res.cloudinary.com/YOUR_CLOUD/image/upload/your-image.jpg <!-- Resized to 1200x630 with fill crop --> https://res.cloudinary.com/YOUR_CLOUD/image/upload/c_fill,w_1200,h_630/your-image.jpg <!-- Use as og:image --> <meta property="og:image" content="https://res.cloudinary.com/YOUR_CLOUD/image/upload/c_fill,w_1200,h_630/your-image.jpg" /> <meta property="og:image:width" content="1200" /> <meta property="og:image:height" content="630" />
Dynamic Text Overlay (Title on Image)
Add dynamic text overlay to a background template image using Cloudinary's text layer transformation:
<!-- Background template + text overlay -->
https://res.cloudinary.com/YOUR_CLOUD/image/upload
/c_fill,w_1200,h_630 (resize background)
/l_text:Arial_60_bold:How%20to%20Fix%20Your%20OG%20Image,
co_white, (white text)
g_west, (align left)
x_80,y_0 (position)
/your-background-template.jpg
<!-- URL-encoded version (what you actually use) -->
https://res.cloudinary.com/YOUR_CLOUD/image/upload/c_fill,w_1200,h_630/l_text:Arial_60_bold:How%20to%20Fix%20Your%20OG%20Image,co_white,g_west,x_80/your-background-template.jpgBuilding a Dynamic OG Image System
The real power: generate unique OG images for every page by building the Cloudinary URL server-side:
// lib/og-image.ts
export function buildCloudinaryOgUrl(title: string): string {
const cloudName = process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME;
const encodedTitle = encodeURIComponent(title.substring(0, 60));
const transforms = [
"c_fill,w_1200,h_630", // resize
`l_text:Arial_56_bold:${encodedTitle},` // text overlay
+ "co_white," // white color
+ "g_west," // left-align
+ "x_80,y_0," // position
+ "w_900", // max text width
].join("/");
return `https://res.cloudinary.com/${cloudName}/image/upload/${transforms}/og-background.jpg`;
}
// In your page component or generateMetadata:
const ogImageUrl = buildCloudinaryOgUrl(post.title);
// → https://res.cloudinary.com/mycloud/image/upload/c_fill,w_1200,h_630/l_text:Arial_56_bold:How%20to%20Fix%20OG%20Tags,co_white,g_west,x_80,y_0,w_900/og-background.jpgUsing the Cloudinary Node.js SDK
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,
});
export function getOgImageUrl(title: string): string {
return cloudinary.url("og-background", {
width: 1200,
height: 630,
crop: "fill",
overlay: {
font_family: "Arial",
font_size: 56,
font_weight: "bold",
text: title.substring(0, 60),
},
color: "white",
gravity: "west",
x: 80,
y: 0,
width: 900,
crop: "fit",
});
}Cloudinary vs @vercel/og
| Feature | Cloudinary | @vercel/og |
|---|---|---|
| Setup | URL parameters or SDK | Edge function / JSX |
| Custom fonts | Limited (system fonts) | Full (any TTF/OTF) |
| Design flexibility | Good (layers, overlays) | High (JSX layout) |
| Cost | Free tier generous | Free on Vercel |
| CDN caching | Cloudinary CDN | Vercel CDN |
| Dynamic per-page | Yes (URL params) | Yes (Edge function) |
Best Practices
- Upload a high-quality base template image (at least 1200×630, ideally 2400×1260 for retina)
- Use
f_auto,q_autoto let Cloudinary choose optimal format and compression - Set
og:image:widthandog:image:heightexplicitly so crawlers don't need to fetch to get dimensions - Verify the generated URL loads correctly before setting it as your og:image
Verify your Cloudinary OG image →
Paste your URL into OGFixer to confirm the Cloudinary-generated image renders correctly on all social platforms.
Preview my OG image →