With more and more success stories emerging daily, content creation has more than proven itself as a viable means of revenue generation. This is mainly due to YouTube’s vast viewership of 300 million daily active users (Q3 2021). A key factor in taking advantage of this audience is a captivating thumbnail that attracts the potential viewer’s attention. YouTube has the following recommendations regarding thumbnails.
An ideal thumbnail should:
- Have a resolution of 1280×720 (with a minimum width of 640 pixels).
- Be uploaded in image formats such as JPG, GIF, or PNG.
- Remain under the 2MB limit.
- Try to use a 16:9 aspect ratio as it’s the most used in YouTube players and previews.
In this article, we will take advantage of Cloudinary to automatically generate simple thumbnails that meet YouTube’s recommendations. By taking advantage of the Transformation URL API, we can specify a URL containing parameters that Cloudinary uses to perform on-the-fly transformations. This provides massive savings as we don’t have to write any code for image manipulation, yet we get a seamless experience that allows us to generate a compliant thumbnail in seconds. You will need a Cloudinary account for this tutorial. If you don’t already have one, create one here.
For UI components in our application, we will use antd while axios will be used to upload our videos to our Cloudinary store.
Our application will take the video title and an image for the thumbnail in a form. On form submission, the image will be uploaded to Cloudinary via an unsigned POST request. From the response, the application will retrieve the stored version and public ID with which it will build a URL and download the image returned by the URL.
Here is a link to the demo on CodeSandbox.
Create a new React app using the following command:
npx create-react-app youtube-thumbnail-generator
Next, add the project dependencies using the following command:
npm install antd @ant-design/icons axiosCode language: CSS (css)
Next, we need to import the antd CSS. To do this, open
src/App.css and edit its content to match the following:
@import '~antd/dist/antd.css';Code language: CSS (css)
Next, we need to create some environment variables to hold our Cloudinary details. For this tutorial, we will be sending images to Cloudinary via unsigned POST requests. To do this, we need our account cloud name and an unsigned upload preset. At the root of the project, create a new file called
.env and add the following to it:
This will be used as a default when the project is set up on another system. To update your local environment, create a copy of the
.env file using the following command:
cp .env .env.localCode language: CSS (css)
By default, this local file is added to
.gitignore and mitigates the security risk of inadvertently exposing secret credentials to the public. You can update
.env.local with your Cloudinary cloud name and the generated upload preset.
Create a new folder named
utility in the project’s
src directory. This folder will hold all the helper classes we need in our components. In the
utility folder, create a file called
cloudinaryConfig.js. This file will give access to the environment variables and prevent repeated
process.env. calls throughout the project. Add the following to the
We need to make two requests for this application – one to upload a new image to Cloudinary and the other to download the image from a URL our application will build. In the
utility folder, create a new file named
api.js and add the following code to it.
uploadVideo function takes a file and a callback function that will be executed when the request is handled successfully. The file and upload preset are passed in a formData request to Cloudinary. The provided success callback is used to trigger further action in the component once a successful response is received. In our case, this will be to download the image from a URL. The
downloadImage function takes the image URL and downloads the image from the URL using the Fetch API. We exported both functions to be used in other parts of our application.
The last utility helper we need is to build an image URL with the relevant parameters for our image transformation. In the
utility folder, create a new file named
urlBuilder.js and add the following code to it:
The default Cloudinary asset delivery URL has the following structure:
Since we’re dealing with images,
<delivery_type> is upload since we’re working with uploaded images. This is how the baseUrl is generated.
Next, we define the
size transformation. Using
c_scale, we scale the image to match the new height and width we specify instead of stretching in one direction. Additionally, we set the width and height using the
h parameters accordingly. Finally, we use the
e_ parameter to apply a sharpen effect on the image.
Next, we define the text overlay transformation. We want the video’s title to be on the image in our generated thumbnail. We start by adding a transparent background using the
b_rgb parameter – the first three digits for the
rgb specification of the color and the last digit for the alpha (transparency) value. Next, we specify the color of the text using the
co_ parameter. Finally, we specify the font using the
l_text parameter. For the font, we can either specify the name of any universally available font or a custom font set as the public ID of a raw, authenticated font in your account. You can get more details on custom fonts here.
To ensure that our title doesn’t exceed the width of the image (which will cause Cloudinary to stretch the image and add a white background to the extra space), we also scale the text overlay to have a relative width of 80% to the generated image.
Next, we specify the location of the text in the title location transformation by using the
[g_](https://cloudinary.com/documentation/transformation_reference#g_gravity) parameters. Finally, we specify the format. For this tutorial, we use
jpg, but as we saw earlier, it could also be
gif, and Cloudinary would still be able to provide the image in that format.
We put everything together in the
buildThumbnailUrl function, which takes the public id and version of the asset along with the video’s title and returns a string corresponding to a Cloudinary transformation URL.
Before we create our components, let’s create a hook to provide helpful functionality for the form we will create.
src directory of the project, create a folder named
hooks, and inside it, create a file called
useFormHelper.js and add the following the following to it:
Our hook takes two parameters –
setIsUploading. When the form is submitted, these parameters are used to update the form UI and pass the uploaded image to Cloudinary.
formItemLayout is an object which contains the size specifications for the label columns in the form to be created.
onFailedSubmission function will be triggered if the validation of the submitted form fails. We log the errors to the console and display a warning message to the user.
onFinish function is called when the form is submitted with valid data. If no image is selected, an error message is shown. If an image is selected, the image is uploaded to Cloudinary using the
uploadImage function. If the request was handled successfully, we retrieve the public id and version from the response and pass them to the
buildThumbnailUrl function along with the submitted image title. Finally, we use the
downloadImage function to download the image from the URL.
src folder, create a new folder called
components. In the
src/components directory, create a new file called
ImageSelector.js and add the following to it:
ImageSelector component takes one prop –
setImage, a callback function that will be used to update the application state with the latest uploaded image by the user.
false in the
beforeUpload key of props, we disable the Upload component’s default behavior, which is to upload the selected file to a provided URL. We also restrict the maximum number of files to 1.
src/App.js file to match the following:
In this component, we declared two state variables – one for the uploaded image and the other for whether or not the image is being uploaded. Next, we use our
useFormHelper hook to get the functionality for the form, passing it the image value in state and the
setIsUploading function, which updates the value of the
isUploading state variable.
Next, we render the form, and it has a single field for the video’s title. The
ImageSelector component is rendered to allow the user to select the thumbnail image. Once the form is filled and an image is selected, the image is uploaded to Cloudinary then a popup is shown, prompting the user to save the downloaded image.
Run your application using the following command:
By default, the application will be available at http://localhost:3000/. The final result will look like the gif shown below.
Find the complete project here on GitHub.
In this article, to use Cloudinary to generate thumbnails for YouTube videos. Additionally, we looked at how Cloudinary can be used to handle the upload and storage of media and the dynamic transformation and rendering of images in a developer-friendly manner. Finally, using antd, we generated a clean and intuitive user interface with minimal code and styling. Taking advantage of the benefits Cloudinary offers makes for optimized images generated in real-time without hassle.
Resources you may find helpful: