Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Pragyat-Nikunj/VidTube/llms.txt

Use this file to discover all available pages before exploring further.

VidTube uses Cloudinary for all media storage — video files, thumbnails, user avatars, and cover images. When a user uploads a file, Multer saves it temporarily to ./public/temp on the server; VidTube then streams it to Cloudinary, deletes the local copy, and stores the returned URL in MongoDB. You need a Cloudinary account before you can run any upload endpoints.

How VidTube uses Cloudinary

VidTube’s Cloudinary utility (src/utils/cloudinary.js) exposes two functions:
  • uploadOnCloudinary(localFilePath) — uploads a file from the local filesystem with resource_type: "auto", which lets Cloudinary auto-detect whether the file is an image or video. On success, the local file is deleted and the Cloudinary response object is returned. On failure, the local file is still deleted and null is returned.
  • deleteFromCloudinary(publicId) — removes a previously uploaded asset by its Cloudinary public ID. Used when a user updates their avatar or a video is deleted.
Here is the utility code that VidTube uses:
import { v2 as cloudinary } from "cloudinary";
import fs from "fs";
import dotenv from "dotenv";

dotenv.config();

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
});

const uploadOnCloudinary = async (localFilePath) => {
  try {
    if (!localFilePath) return null;
    const response = await cloudinary.uploader.upload(localFilePath, {
      resource_type: "auto",
    });
    console.log("File uploaded on cloudinary. File src: " + response.url);
    // Delete the local temp file after a successful upload
    fs.unlinkSync(localFilePath);
    return response;
  } catch (error) {
    console.log("Error on Cloudinary", error);
    fs.unlinkSync(localFilePath);
    return null;
  }
};

const deleteFromCloudinary = async (publicId) => {
  try {
    const result = await cloudinary.uploader.destroy(publicId);
    console.log("Deleted from cloudinary. Public id: ", publicId);
  } catch (error) {
    console.log("Error deleting from cloudinary", error);
    return null;
  }
};

export { uploadOnCloudinary, deleteFromCloudinary };

What gets stored

AssetField nameUpload behavior
Video filevideoFileUploaded with resource_type: auto
ThumbnailthumbnailUploaded with resource_type: auto
User avataravatarUploaded on register; old asset deleted when updated
Cover imagecoverImageOptional; uploaded on register if provided

Set up Cloudinary

1

Create a free Cloudinary account

Go to cloudinary.com and sign up for a free account. No credit card is required to start.
2

Find your credentials

After signing in, open the Cloudinary Dashboard. At the top of the page you will see your:
  • Cloud name — a unique identifier for your Cloudinary environment (e.g., my-cloud)
  • API key — a numeric key used to identify your account in API requests
  • API secret — a private secret that authorizes writes, deletes, and signed uploads
Keep your API secret private. Anyone with your API secret can upload to or delete from your account.
3

Add the credentials to your `.env` file

Open your project’s .env file and add the three Cloudinary variables:
CLOUDINARY_CLOUD_NAME=my-cloud
CLOUDINARY_API_KEY=123456789012345
CLOUDINARY_API_SECRET=abc123xyzSuperSecretValue
Replace the values with the ones from your Cloudinary Dashboard.
4

Restart the server

If your server is already running, restart it so it picks up the new environment variables:
npm run dev
VidTube will configure the Cloudinary SDK on startup. If any of the three variables are missing, uploads will fail silently and uploadOnCloudinary will return null.
Cloudinary’s free plan includes 25 credits per month and up to 1 GB of storage. A credit roughly corresponds to one transformation or one upload action. For development and light testing, the free plan is sufficient. Refer to the Cloudinary pricing page for details on paid plans.

Upload flow

Every file upload in VidTube follows this sequence:
  1. The client sends a multipart/form-data request.
  2. Multer intercepts the request and saves the file to ./public/temp on the server disk.
  3. The controller calls uploadOnCloudinary with the temporary file path.
  4. Cloudinary receives the file, stores it, and returns a response containing the public URL and public ID.
  5. VidTube stores the URL and public ID in MongoDB, then deletes the local temp file.
If Cloudinary returns an error at step 4, the temp file is still deleted and the controller receives null. The controller should handle this case and return a 500 error to the client.
If you need client-side (browser-direct) uploads without routing files through your server, Cloudinary supports unsigned upload presets. Create a preset in your Cloudinary Settings under Upload, set it to unsigned, and use the Cloudinary JavaScript SDK directly from the browser. This approach bypasses Multer and the VidTube upload utility entirely.

Build docs developers (and LLMs) love