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.jpg

Building 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.jpg

Using 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

FeatureCloudinary@vercel/og
SetupURL parameters or SDKEdge function / JSX
Custom fontsLimited (system fonts)Full (any TTF/OTF)
Design flexibilityGood (layers, overlays)High (JSX layout)
CostFree tier generousFree on Vercel
CDN cachingCloudinary CDNVercel CDN
Dynamic per-pageYes (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_auto to let Cloudinary choose optimal format and compression
  • Set og:image:width and og:image:height explicitly 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 →