Skip to content

How to Optimize Video in Next.js With Cloudinary

Users worldwide have varying internet speeds, data caps, and other restrictions, making it difficult to stream heavy content like videos. To ensure a smooth experience, videos must be compressed and optimized to load quickly without sacrificing quality.

In this blog post, I’ll show you how to create a custom video player in Next.js while leveraging Cloudinary for video optimization and delivery. We’ll use Cloudinary to ensure that videos are served in a format that suits the user’s device, reducing load times and improving performance. By the end, you’ll have a fully functional and optimized video player integrated into your Next.js app with minimal effort.

To get started, I used the command npx create-next-app@latest and followed the prompts.

Once the project was ready, I added the next-cloudinary package by running:

npm install next-cloudinary

After that, I set the NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME environment variable in my .env.local file so Cloudinary could adequately handle the image hosting.

To optimize video delivery in our Next.js app, I created a custom video player component using next-cloudinary. This allows us to use Cloudinary’s optimization features while keeping the implementation simple.

Here’s the code for the custom VideoPlayer component:

"use client";
import { CldVideoPlayer, CldVideoPlayerProps } from "next-cloudinary";
import "next-cloudinary/dist/cld-video-player.css";

export default function VideoPlayer(options: {
  src: string;
  width: string | number;
  height: string | number;
  variant?: "primary" | "background";
  className?: string;
}) {
  const { src, width, height, variant = "primary", className = "" } = options;

  // See https://cloudinary.com/glossary/video-autoplay
  let specialOptions: Partial<CldVideoPlayerProps> = {};
  if (variant === "background") {
    specialOptions = {
      autoplay: true,
      muted: true,
      loop: true,
      controls: false,
    };
  }

  return (
    <CldVideoPlayer
      src={src}
      width={width}
      height={height}
      className={`${className} ${
        variant === "background" ? "cursor-default" : ""
      }`}
      transformation={{
        fetch_format: "auto",
        quality: variant === "primary" ? "auto:good" : "auto:low",
        crop: "fill",
      }}
      {...specialOptions}
    />
  );
}
Code language: JavaScript (javascript)

This component utilizes Cloudinary’s CldVideoPlayer to handle video optimization automatically. The VideoPlayer component accepts several props:

  • src. The source of the video, which should be the public ID of your video on Cloudinary.
  • width and height. Define the dimensions of the video player.
  • variant. This optional prop lets you choose between two styles: "primary" (for regular video playback) and "background" (for auto-playing background videos without controls).
  • className. Additional classes for custom styling.

The variant prop is especially useful, allowing us to switch between different optimization options. For example, when the video is used as a background, the component automatically applies lower-quality settings and removes controls to save resources. For a primary video, it serves well using Cloudinary’s auto format and quality options for the best user experience.

Cloudinary provides excellent control and performance when using the auto format and quality options, as it automatically adjusts the video for optimal delivery based on the user’s device and connection speed. This is a simple but effective way to ensure videos load quickly without compromising quality.

However, I highly recommend checking out Cloudinary’s video optimization documentation for more advanced performance optimization strategies. Depending on your specific use case, you can apply many tips and techniques, such as choosing different formats, adjusting bitrates, or using adaptive bitrate streaming.

Now that we have the custom video player component let’s put it to use on the home page. Here’s a simple example where I use the video player in “primary” mode to showcase a video from Cloudinary:

import VideoPlayer from "@/components/video-player/VideoPlayer.client";

export default function Home() {
  return (
    <div className="flex items-center justify-center h-screen w-full">
      <div className="w-1/2">
        <VideoPlayer src="samples/sea-turtle" width={1920} height={1080} />
      </div>
    </div>
  );
}
Code language: JavaScript (javascript)

In this example, the video is displayed in the center of the screen in “primary” mode, using the VideoPlayer component with a 1920×1080 resolution. The video is served in an optimized format, ensuring good performance across devices. Here’s a preview of the result:

video player example in primary mode

Next, we can switch the player to “background” mode by passing the variant="background" prop. This makes the video autoplay in the background without controls, perfect for use cases where you want a looping, muted background video:

<VideoPlayer src="samples/sea-turtle" width={1920} height={1080} variant="background" />
Code language: HTML, XML (xml)

Here’s a preview of how it looks:

video player example in background mode

By using different modes, you can quickly adapt the video player to fit your specific needs, whether showcasing video content or enhancing the user experience with a background video.

Combining Next.js and Cloudinary allows you to easily create a custom video player that serves videos in the most efficient format and quality, adapting to different use cases like primary content or background visuals.

For more in-depth tips and strategies on video optimization for the web, I highly recommend checking out this other post on the Cloudinary Blog: Optimize Video for the Web Using Cloudinary. It’s an excellent resource for learning about advanced techniques to help you take your video performance even further. And to try Cloudinary, sign up for a free account today.

Thanks for following along, and I hope this post helps you optimize video content in your Next.js applications!

If you found this blog post helpful and want to discuss it in more detail, head over to the Cloudinary Community forum and its associated Discord.

Back to top

Featured Post