Optimize with Netlify-plugin-cloudinary in Next.js

Demola Malomo

Images are an essential part of websites and web applications. As the web becomes more visual, developers and engineers constantly build tools and applications to reduce page load time and improve the overall user experience.

This post will discuss optimizing and delivering image assets with Netlify-plugin-cloudinary in a Next.js application. In a nutshell, this plugin automatically optimizes and serves your website images during deployment, using Cloudinary.

At the end of this tutorial, we will learn how to build an image gallery using Next.js, host the source code on Github, deploy it to Netlify, and automatically serve optimized images using Cloudinary.

Sandbox

We completed this project in a CodeSandbox. Fork and run it to quickly get started.

Github link here.

View deployed version on Netlify here.

Prerequisites

To fully grasp the concepts presented in this tutorial, a good knowledge of JavaScript and React.js is required. Experience with Next.js isn’t a requirement, but it’s nice to have.

We also need the following:

Getting Started

We need to create a Next.js starter project by navigating to the desired directory and running the command below in our terminal.

1npx create-next-app next_opt_image && cd next_opt_image

The command creates a Next.js project called next_opt_image, and navigates to the project directory.

Creating an image gallery with Next.js

To create an image gallery, we need to navigate to the URL below and download sample images from Unsplash:

With that done, we need to navigate to the public folder, and in this folder, create an images folder, copy and paste all the downloaded images.

Next, we need to create a utils folder in the project root directory. In this folder, we create an images.json file. The file contains image data for the gallery.

images.json

1[
2 {
3 "id": 1,
4 "name": "Mustang",
5 "url": "/images/mustang.jpg"
6 },
7 {
8 "id": 2,
9 "name": "Ferrari",
10 "url": "/images/ferrari.jpg"
11 },
12 {
13 "id": 3,
14 "name": "BMW",
15 "url": "/images/bmw.jpg"
16 },
17 {
18 "id": 4,
19 "name": "Mercedes",
20 "url": "/images/mercedes.jpg"
21 }
22]

With that done, we can leverage Next.js CSS Module support to style our page by replacing the content in Home.module.css in the styles folder with the code snippet below:

1.container {
2 padding: 0 2rem;
3}
4
5.main {
6 min-height: 100vh;
7 padding: 4rem 0;
8 flex: 1;
9 display: flex;
10 flex-direction: column;
11 justify-content: center;
12 align-items: center;
13}
14
15.title {
16 margin: 0;
17 line-height: 1.15;
18 font-size: 4rem;
19}
20
21.title,
22.description {
23 text-align: center;
24}
25
26.grid {
27 display: flex;
28 align-items: center;
29 justify-content: center;
30 flex-wrap: wrap;
31 max-width: 800px;
32}
33
34.card {
35 margin: 1rem;
36 padding: 1.5rem;
37 text-align: left;
38 color: inherit;
39 text-decoration: none;
40 border: 1px solid #eaeaea;
41 border-radius: 10px;
42 transition: color 0.15s ease, border-color 0.15s ease;
43 max-width: 300px;
44}
45
46.card img {
47 height: 100%;
48 width: 100%;
49}
50
51.card p {
52 margin: 0;
53 font-size: 1rem;
54}
55
56
57@media (max-width: 600px) {
58 .grid {
59 width: 100%;
60 flex-direction: column;
61 }
62}

Next, we modify the index.js file in the pages folder to the following:

1import Head from 'next/head';
2import styles from '../styles/Home.module.css';
3import images from '../utils/images.json'; //add this
4
5export default function Home() {
6 return (
7 <div className={styles.container}>
8 <Head>
9 <title>Next Cloudinary Image</title>
10 <meta name='description' content='Next Cloudinary Image' />
11 <link rel='icon' href='/favicon.ico' />
12 </Head>
13 <main className={styles.main}>
14 <h1 className={styles.title}>Optimized Image Gallery</h1>
15 <div className={styles.grid}>
16 {images.map((image) => (
17 <div key={image.id} className={styles.card}>
18 <img src={image.url} alt={image.name} />
19 <p>{image.name}</p>
20 </div>
21 ))}
22 </div>
23 </main>
24 </div>
25 );
26}

The snippet above does the following:

  • Imports the image collection.
  • Markup shows the list of images by looping through the image collection.

With that done, we can start a development server using the command below:

1npm run dev

Pushing our source code to Github

We want to push our source code to GitHub to facilitate a speedy “deploy from GitHub” workflow on Netlify. To get started, we need to log into our Github dashboard. Click on the plus icon and select New Repository.

Input next_opt_image as the Repository name and click on Create repository.

Next, run the command below to add and save recent changes

1git add .
2git commit -m "add image gallery"

Copy and run the highlighted commands on the terminal:

We can refresh the browser to see updated changes to our repository.

Deploying to Netlify

To get started, we need to log into our Netlify dashboard. Click on Add new site dropdown and select Import an existing project.

Select Github as the Git provider and authorize Netlify.

Search for next_opt_image and select the repository.

Click on Deploy Site to start deployment. It might take a few minutes.

We can view the deployed site by clicking on the generated URL.

Optimizing and delivering images with Netlify-plugin-cloudinary

Before optimizing the images in our application, let’s open the developer tools, navigate to the Network tab, and refresh the page to see how the images are currently being served and their sizes.

We can also click on any image to see the image URL and the provider serving it.

Netlify-plugin-cloudinary

The Netlify-plugin-cloudinary is a plugin that hooks into Netlify when deploying websites and applications to serve smaller images in modern formats automatically. We don't have to upload the images manually, get the URL, and embed them into our codebase with the plugin.

To improve the performance of our image gallery, we will be integrating the plugin into our deployment process.

To begin, we proceed to install the netlify-plugin-cloudinary dependency with:

1npm install netlify-plugin-cloudinary

Next, we need to create a netlify.toml file in the project root directory and add the code snippet below:

1[[plugins]]
2 package = "netlify-plugin-cloudinary"
3
4 [plugins.inputs]
5 cloudName = "<Your Cloud Name>"

The snippet above does the following:

  • Defines netlify-plugin-cloudinary as the required plugin.
  • Sets the plugin input to our cloudName. The cloudName helps Cloudinary know the account to which the images should be attached.

Finally, we need to commit our changes and push them to the repository by running the command below in the terminal:

1git add .
2git commit -m "add support for optimization"
3git push origin main

On doing this, Netlify will redeploy the latest changes.

We can inspect the deployed version to see image format, size, and how the images are being served.

Conclusion

This post discussed how to automatically optimize and deliver image assets with Netlify-plugin-cloudinary in a Next.js application.

These resources might be helpful:

Demola Malomo

Software Engineer & Technical Writer

Demola is a software developer, technical writer, and product designer. He has a passion for designing and building scalable applications.