Cloudinary is a cloud media management service (SaaS) that handles uploading, storage, on-the-fly transformations (resize/crop/format/quality), optimization and CDN delivery for images and videos. It provides REST APIs and SDKs for frontends and backends so you can offload media work to a specialist service instead of your own servers.
Start learning how to build softwares
Benefits of using Cloudinary
- Fast delivery & global CDN — serves optimized assets from edge locations for lower latency.
- Automatic optimization & responsive images — generate properly sized, WebP/AVIF, quality-adjusted variants on demand.
- Server- or client-side uploads — flexible: direct browser uploads (unsigned or signed) or upload via your backend.
- Powerful transformations in URL or SDK — crop, format, overlays, watermark, video transforms, etc., without re-uploading.
- Asset management — tagging, search, versions, access controls and dashboard.
Quick plan
- Display Cloudinary-hosted images in React (use Cloudinary React SDK).
- Upload images from React — choose between:
- Upload Widget (easy, hosted UI) — good for quick UX.
- Unsigned direct client uploads (fast but less secure) — create an unsigned upload preset.
- Signed direct client uploads (recommended for protected apps) — generate signature/server token on your backend using Cloudinary server SDK.
Step-by-step: set up Cloudinary + React
Step-by-step: set up Cloudinary + React
1) Create Cloudinary account & get credentials
- Sign up at cloudinary.com. In the Dashboard you’ll find cloud name, API key, API secret (keep secret). You’ll need the cloud name in the client and API key/secret for server signing.
2) Decide upload flow & (optional) create upload preset
- For unsigned client uploads or the Upload Widget create an unsigned upload preset in Console → Settings → Upload → Upload presets. This preset name is passed from the client. (Unsigned = no API secret needed, but less control/security).
3) Install Cloudinary React packages
From your React project root:
npm install @cloudinary/react @cloudinary/url-gen
# or
yarn add @cloudinary/react @cloudinary/url-gen
(These are Cloudinary’s current frontend SDKs for React + URL generation/transformations.)
4) Configure SDK & render images in React
Create a Cloudinary instance and render an image with AdvancedImage.
Example CloudinaryProvider usage (simple):
// src/cloudinary.js
import { Cloudinary } from "@cloudinary/url-gen";
export const cld = new Cloudinary({
cloud: { cloudName: process.env.REACT_APP_CLOUDINARY_CLOUD_NAME }
});
Example component showing an image and simple transform:
// src/components/Photo.jsx
import React from "react";
import { AdvancedImage } from "@cloudinary/react";
import { cld } from "../cloudinary";
import { fill } from "@cloudinary/url-gen/actions/resize";
export default function Photo({ publicId }) {
// build image with transformations
const myImage = cld.image(publicId).resize(fill().width(400).height(300));
return <AdvancedImage cldImg={myImage} alt="Uploaded asset" />;
}
This uses Cloudinary URL-Gen to create a URL with transforms, and AdvancedImage renders it with lazy loading and other optimizations.
5) Uploading from React — three common approaches
A — Cloudinary Upload Widget (fastest)
- Widget is a Cloudinary JS component you mount; it handles UI and uploads to your cloud.
- Requires
cloud_nameand an unsigned upload preset (unless you use server-signed widget).
Minimal example:
// UploadWidget.jsx
import React, { useEffect } from "react";
export default function UploadWidget({ onUpload }) {
useEffect(() => {
// ensure widget script loaded (you can include script in index.html or dynamically)
const widget = window.cloudinary.createUploadWidget(
{
cloudName: process.env.REACT_APP_CLOUDINARY_CLOUD_NAME,
uploadPreset: "your_unsigned_preset"
},
(error, result) => {
if (!error && result && result.event === "success") {
onUpload(result.info); // result.info has public_id, secure_url, etc.
}
}
);
// attach to a button
document.getElementById("uploadBtn").addEventListener("click", () => widget.open(), false);
}, [onUpload]);
return <button id="uploadBtn">Upload image</button>;
}
Pros: very easy, great UX.
Cons: limited customization unless you roll your own; unsigned presets may be abused if public.
B — Direct unsigned upload (fetch / form-data) — client posts to Cloudinary upload endpoint
- Use when you want a custom UI but accept unsigned uploads.
- Example:
async function uploadFile(file) {
const url = `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/upload`;
const formData = new FormData();
formData.append("file", file);
formData.append("upload_preset", "your_unsigned_preset");
const res = await fetch(url, { method: "POST", body: formData });
const data = await res.json();
return data; // contains public_id, secure_url...
}
Security note: unsigned uploads are easier but the preset controls allowed parameters — still less safe for sensitive apps.
C — Signed upload (recommended for protected apps) — brief overview + Node example
Why signed? Signed uploads require a signature from your server (which has the API secret), preventing malicious clients from arbitrarily setting upload parameters, folders, or using privileges you don’t intend to expose.
Flow: client asks your server for a timestamp + signature (and maybe api_key); server generates signature using API secret; client calls Cloudinary upload endpoint with file + signature + timestamp.
Server: Node/Express example to generate signature
// server/signature.js
require("dotenv").config();
const express = require("express");
const crypto = require("crypto");
const app = express();
app.get("/signature", (req, res) => {
const timestamp = Math.round(Date.now() / 1000);
// include any params you want to sign (e.g., folder, eager, public_id)
const paramsToSign = `timestamp=${timestamp}${process.env.CLOUDINARY_API_SECRET}`;
const signature = crypto.createHash("sha1").update(paramsToSign).digest("hex");
res.json({
timestamp,
signature,
api_key: process.env.CLOUDINARY_API_KEY // client needs api_key too
});
});
app.listen(3001);
(Cloudinary has helper methods in backend SDKs that produce the signature for you — prefer the official cloudinaryNode SDK for production. Docs: generating signatures & Node SDK.)
Client: using the signature to upload
async function uploadSigned(file) {
// 1. get signature + timestamp from your server
const sigRes = await fetch("/signature");
const { signature, timestamp, api_key } = await sigRes.json();
// 2. upload to Cloudinary
const formData = new FormData();
formData.append("file", file);
formData.append("api_key", api_key);
formData.append("timestamp", timestamp);
formData.append("signature", signature);
const res = await fetch(`https://api.cloudinary.com/v1_1/${CLOUD_NAME}/upload`, {
method: "POST",
body: formData
});
return await res.json();
}
6) After upload: storing/using the result
- Cloudinary returns
public_id,secure_url, width/height, format, etc. Storepublic_idorsecure_urlin your DB for later display. Usepublic_idwith URL-Gen to apply transformations easily.
Best practices & tips
- Never expose your API secret in client code — use signed uploads for secure flows.
- Use upload presets to control where files land, transformations, moderation, allowed formats. Unsigned presets allow client uploads without signing but limit what can be passed.
- Leverage transformations & responsive images (generate different sizes, use
srcsetwithAdvancedImagebehavior). This reduces bandwidth and improves performance. - Cache & CDN headers — Cloudinary sets proper caching; combine with versioning when you overwrite assets.
- Security controls — consider authenticated signed uploads, moderation rules, and folder access settings if you accept user content.
Quick checklist to get started now
- Sign up at Cloudinary → copy cloud name and API key.
- Create an unsigned upload preset if you’ll start with client uploads or enable signed uploads via backend for production.
npm i @cloudinary/react @cloudinary/url-genin your React app.- Use
AdvancedImage+url-gento display images andcreateUploadWidgetor direct upload code for uploads.
Summary
Cloudinary is a powerful cloud-based media management service that helps developers easily upload, store, optimize, and deliver images and videos in React applications. By integrating Cloudinary with React, you can offload complex image handling tasks—like resizing, transformation, and CDN delivery—to Cloudinary’s infrastructure. Using the React SDK and Upload Widget (or API), developers can quickly implement secure client-side uploads, display optimized media, and ensure high performance across devices while maintaining control over asset management and transformations.

Latest tech news and coding tips.