October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Use Cloudinary’s Image and Video API with Astro

A practical guide to server-side Cloudinary uploads in Astro, from multipart forms and credential safety to image and video transformations and asset access.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Astro’s server-side route to accept an image or video, upload its bytes to Cloudinary, and render the returned asset URL. Cloudinary stores and delivers the media; transformation parameters in its delivery URLs control the image or video output. The browser should not receive your Cloudinary API secret.

How the Astro and Cloudinary flow works

A visitor submits a multipart form to an Astro server-capable route. The route validates the file, sends it to Cloudinary with the Node.js SDK, then uses the upload result—especially the public ID and version—to construct a delivery URL. Astro renders a preview using that URL. Cloudinary makes an uploaded asset available for transformation and delivery after the upload completes.

As an Amazon Associate I earn from qualifying purchases.

Cloudinary’s Astro upload tutorial, last updated June 2, 2026, demonstrates this server-side pattern with upload_stream. The deployment must support server-side request handling: a static-only page cannot process the upload on its own. Configure an Astro server or hybrid output and deploy with an adapter or server endpoint appropriate to your host.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Configure Astro for server-side uploads

In astro.config.mjs, set the output to server or hybrid rather than relying on static output for the upload handler:

import { defineConfig } from 'astro/config';

export default defineConfig({
  output: 'server',
});

Keep Cloudinary credentials in server-only environment variables. For example, provide CLOUDINARY_CLOUD_NAME, CLOUDINARY_API_KEY, and CLOUDINARY_API_SECRET through your local environment and deployment secret manager. Do not prefix secrets with a setting that exposes them to browser code.

Build a multipart upload route

Install Cloudinary’s Node.js SDK and add a route such as src/pages/upload.astro. This example accepts an image or video, imposes a sample 20 MB application limit, and uploads through Cloudinary’s stream API. Adjust the size and permitted types to match your application and account configuration.

import { v2 as cloudinary } from 'cloudinary';

cloudinary.config({
  cloud_name: import.meta.env.CLOUDINARY_CLOUD_NAME,
  api_key: import.meta.env.CLOUDINARY_API_KEY,
  api_secret: import.meta.env.CLOUDINARY_API_SECRET,
  secure: true,
});

function uploadBuffer(buffer, resourceType) {
  return new Promise((resolve, reject) => {
    const stream = cloudinary.uploader.upload_stream(
      { resource_type: resourceType },
      (error, result) => {
        if (error) reject(error);
        else resolve(result);
      },
    );
    stream.end(buffer);
  });
}

let uploaded;
let errorMessage;

if (Astro.request.method === 'POST') {
  try {
    const form = await Astro.request.formData();
    const value = form.get('file');

    if (!(value instanceof File) || value.size === 0) {
      throw new Error('Choose a non-empty file.');
    }
    if (value.size > 20 * 1024 * 1024) {
      throw new Error('The file must be 20 MB or smaller.');
    }

    const allowed = new Map([
      ['image/jpeg', 'image'],
      ['image/png', 'image'],
      ['image/webp', 'image'],
      ['video/mp4', 'video'],
      ['video/webm', 'video'],
    ]);
    const resourceType = allowed.get(value.type);
    if (!resourceType) {
      throw new Error('Use a JPEG, PNG, WebP, MP4, or WebM file.');
    }

    const buffer = Buffer.from(await value.arrayBuffer());
    uploaded = await uploadBuffer(buffer, resourceType);
  } catch (error) {
    errorMessage = error instanceof Error ? error.message : 'Upload failed.';
  }
}

const previewUrl = uploaded?.secure_url;
const assetType = uploaded?.resource_type;

The type allowlist and size check are application safeguards, not a substitute for validating content on a production system. Client-provided MIME types can be spoofed; if uploads are sensitive or exposed to abuse, validate file signatures and enforce rate limits and authorization as appropriate. Large files also consume memory in this buffered example. Use a streaming design or direct-to-Cloudinary flow when the server’s memory and request limits make buffering unsuitable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Render the form and result in the same route:

<form method="post" enctype="multipart/form-data">
  <label for="file">Image or video</label>
  <input id="file" name="file" type="file" accept="image/jpeg,image/png,image/webp,video/mp4,video/webm" required />
  <button type="submit">Upload</button>
</form>

{errorMessage && <p role="alert">{errorMessage}</p>}

{previewUrl && assetType === 'image' && (
  <img src={previewUrl} alt="Uploaded image" />
)}

{previewUrl && assetType === 'video' && (
  <video src={previewUrl} controls />
)}

In a larger application, a dedicated Astro endpoint or action can keep upload logic separate from presentation. Return only the fields the client needs; do not expose secrets or unnecessary upload response data.

Choose the upload trust boundary

Cloudinary’s REST upload endpoint follows https://api.cloudinary.com/v1_1/<cloud name>/<resource_type>/upload, where the resource type can be image, raw, video, or auto. Cloudinary supports authenticated and unauthenticated uploads; unauthenticated uploads have security restrictions. Signed upload presets can define optional parameters.

  • Server-side SDK upload: The Astro server holds the API secret and mediates the file upload. This is the approach in Cloudinary’s Astro tutorial. It lets your application apply its own authorization and validation before sending data.
  • Direct browser upload: A browser can upload using a deliberately configured unsigned preset, without receiving the API secret. Use this only with the preset’s restrictions and an abuse-control strategy that fit your threat model.

Choose based on who may upload, what validation is required, file size, and whether requests should pass through your Astro deployment. A server-side route gives your application a control point but adds server bandwidth, request-size, timeout, and memory considerations.

Render transformed images and videos

Understand delivery URLs

A Cloudinary delivery URL identifies the cloud name, asset type, delivery type, optional transformations, optional version, and public ID. For example, an image URL has the general shape https://res.cloudinary.com/<cloud-name>/image/upload/<transformations>/v<version>/<public-id>. Use the identifiers returned by the upload rather than guessing the public ID. Cloudinary’s image transformation documentation covers URL-based transformations and SDK URL builders.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Transformations can resize, crop, change format, and adjust quality. For an Astro image preview with responsive resizing or automatic format conversion, the tutorial points to unpic. Transformation URLs also work directly in rendered image markup when a fixed or otherwise suitable size is enough.

Transform videos

Video delivery uses the video asset type and supports transformations. Cloudinary documents resizing, cropping, rotation, quality and format changes, automatic quality or format, and overlays in its video transformation guide. Use a video player integration only if the application needs player-specific behavior; uploading and previewing a video does not by itself require one. See the JavaScript video documentation for player and streaming capabilities.

Plan for derivative creation and caching

Cloudinary generates a derived transformation on first access and caches it on the CDN for later requests. The initial request for a new transformation may therefore behave differently from repeat requests. Prefer a consistent set of transformations rather than generating arbitrary variants from untrusted user input.

Set asset access deliberately

Do not treat every uploaded asset as private by default. Cloudinary documents distinct delivery behavior for upload, private, and authenticated delivery types in its access control documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Upload delivery type: Generally publicly accessible, though Cloudinary documents restrictions that can be configured.
  • Private: The original requires a signed URL; transformed versions may be public unless strict transformations are configured.
  • Authenticated: Originals and transformed versions require a signed URL or authentication token.

Choose the delivery type for the asset’s sensitivity and access model before exposing its URL in a page, feed, or API response. A URL embedded in public HTML is not a secret.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

  • The form reloads but no upload runs: Confirm the route handles POST, the form uses enctype="multipart/form-data", and the deployed Astro output supports server-side execution.
  • Cloudinary reports an authentication or configuration error: Check that the cloud name, API key, and secret are present in the server environment and correspond to the same Cloudinary account. Restart or redeploy after changing environment variables.
  • The file field is missing or empty: Verify that the input has the expected name, the form uses multipart encoding, and the route reads the same field name from formData().
  • The upload fails only for large files: Check request-size and timeout limits imposed by the host and available memory. The sample buffers the complete file before upload, so large media may require streaming or a direct upload design.
  • A video is delivered as an image or vice versa: Pass the correct resource_type to the SDK or use the matching REST endpoint path. Cloudinary supports image, video, raw, and auto.
  • A transformed URL returns an access error: Check the delivery type and whether the requested original or transformation needs signing or an authentication token.
  • A new transformation appears slower than later requests: Cloudinary creates derived assets on first access and caches them on the CDN for subsequent requests.

Or skip the browser setup

If what you need is a screenshot of a web page rather than an uploaded image or video, ScreenshotNeo is a separate website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; see the API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, with response headers indicating the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up free for 1,000 screenshots a month, with no card required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I use Cloudinary uploads with a static-only Astro deployment?

Not with the server-side route shown here. Use server or hybrid output with a compatible deployment adapter, or implement a separately hosted upload endpoint.

Does uploading a video require Cloudinary’s video player?

No. A video can be uploaded and delivered with a video URL and standard HTML controls. A player is relevant when you need its additional playback or streaming capabilities.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.