Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteUse 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.
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:
#1 Best Overall
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.
Rank #2
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.
Recommended Free Tools
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.
Rank #4
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.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →- 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.
Best Value
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 fromformData(). - 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_typeto the SDK or use the matching REST endpoint path. Cloudinary supportsimage,video,raw, andauto. - 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.
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.
Quick Recap
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.




