How to Optimize Images on Netlify with the Cloudinary Build Plugin
Netlify makes building and deploying Jamstack apps super easy, but without additional tools, your images are going to get deployed “as is”, leaving lots of potential room for saving precious bytes. Instead, we can use the Cloudinary Netlify Plugin and get automatic optimization and modern formatting to make sure we’re delivering as great and lean of an experience as we can.
What is Netlify?
Netlify is a hosting and automation platform that gives developers an easy way to build projects and deploy them to the web. It has a variety of features on top of that including serverless functions and forms, but we’re going to primarily look at simply deploying an app to the web.
What is a Netlify Build Plugin?
During the build and deploy process, Netlify provides hooks at different stages, allowing not only Netlify to add functionality to the process, but for developers to hook in with plugins.
For instance, if you wanted to run some set of functionality after the build completes on the output (like HTML, CSS, JS), we can run a build plugin “post-build”.
This is exactly how the Cloudinary Build Plugin works, which allows you to not only serve all your images from Cloudinary, but transform your images as well.
Why would we want to transform and serve our images with Cloudinary?
While Netlify will certainly serve your assets from a wonderful CDN, Cloudinary is able to provide additional benefits on top of serving from a CDN, including things like auto-optimization along with automatically serving the image with modern formats (like WebP, AVIF) if the browser requesting the image supports it.
This is a big deal, where typically this process is manual or cumbersome or it doesn’t even happen at all. Optimizing images and how we serve them help avoid long page loads for mobile users or those with slow internet connections and potentially eating up limited bandwidth.
What are we going to build?
So to test this out, we’re going to see how we can set up the Cloudinary Build Plugin on a deploy Netlify site.
To do this, we’re going to first deploy a simple web app example to Netlify as our base project.
Then, we’ll learn how we can use Cloudinary and install the Build Plugin to automatically optimize our images!
Disclaimer: I work for Cloudinary as a Developer Experience Engineer.
Step 0: Creating a new Next.js app from a demo starter
We’re going to start off with a new Next.js app using a simple image gallery of character posters from the TV series Arcane.
Inside of your terminal, run:
yarn create next-app my-arcane-wiki -e https://github.com/colbyfayock/demo-arcane-wiki # or npx create-next-app my-arcane-wiki -e https://github.com/colbyfayock/demo-arcane-wiki
Note: feel free to use a different value than
my-arcane-wikias your project name!
Once installation has finished, you can navigate to that directory and start up your development server:
cd my-arcane-wiki yarn dev # or npm run dev
And once loaded, you should now be able to open up your new app at http://localhost:3000!
Now what we’ll be focusing on in this application are the images. Specifically, we have our logo image along with a gallery of character posters.
Those are being served locally from the application and as we’ll see in Step 1, when deployed to Netlify, Netlify will serve those images from their own CDN.
We’ll later see how we can automatically optimize those images with Cloudinary!
Step 1: Deploying an application to Netlify
We have a few options to deploy our application to Netlify.
So starting off for this walkthrough, we’ll need our application hosted in GitHub. If you’re not familiar with this process, you can head over to the GitHub docs and learn how to add an existing project to GitHub using the command line.
Once your project is on Netlify though, we can get started by clicking the New site from Git button inside of our Netlify dashboard.
On the next page, you’ll be asked to select your Git provider in order to import a project. Again, I’m using GitHub so if you’re following along, you can go ahead and select GitHub, otherwise select your Git provider of choice.
When doing so if you haven’t already, you’ll be asked to authenticate your account with Netlify, which gives Netlify the ability to grab your project as well as provide additional capabilities such as monitoring pull requests for creating automatic deployments.
But once authenticated, you’ll be asked to select your repository from Git!
Select your repository and next we’ll see a configuration page.
One of the cool things about Netlify is it has the ability to automatically detect what kind of project you have. Because we have a Next.js project, Netlify sees that, and subsequently will install the Essential Next.js Build Plugin as well as specify the Build Command and Publish Directory for us.
So at this point, we can simply click Deploy site at the bottom and watch our project kick off!
On the next page, we’ll see that Netlify will give us a randomly generated site name and we’ll additionally see our new build in progress.
Once that’s complete, you’ll be able to open your new site and see it deployed to the web.
Now before we move on, if we open up the Network tab when visiting our site and look at the images, we can see that they’re all being served directly from Netlify.
If our images are already optimized, we might be fine simply serving them “as is”. But if they’re not, we’re sending images and wasting people’s bandwidth.
On top of that, we’re still serving them as JPEG files, which again is fine, but we can do better, which is where Cloudinary comes in!
Step 2: Installing and configuring the Cloudinary Build Plugin for Netlify
At the time of writing this article, the Cloudinary Build Plugin isn’t available quite yet to install right from the Netlify UI, so that means we’ll need to install it locally in our project using a Netlify configuration file and installing it as a package with npm.
Let’s start off by installing the package.
In your terminal, run:
yarn add netlify-plugin-cloudinary # or npm install netlify-plugin-cloudinary
Next, we want to set up our new Netlify configuration file.
Note: if you’re using your own project and already have your configuration file, you can simply add it to your existing one!
In the root of your project, create a new file
netlify.toml and add:
[[plugins]] package = "netlify-plugin-cloudinary" [plugins.inputs] cloudName = "[Your Cloud Name]"
Here we’re telling Netlify that we want to use the Cloudinary Build Plugin. We’re also specifying an input, particularly our Cloudinary Cloud Name, which we can get right inside our Cloudinary account.
To find your Cloud Name, head over to Cloudinary, log in, and at the top of the dashboard, you should be able to see and copy your Cloud Name.
Note: make sure to use your own Cloud Name and not mine, as that account is limited and might not work. You can get your own free account over at cloudinary.com.
Once you configured your Netlify config, go ahead and commit that file and push it out to GitHub or your Git provider.
Another cool thing about Netlify is as soon as you make a change on your main branch, by default, Netlify will kick off a new deploy, meaning we don’t need to do anything and can sit back and watch it work!
After the build finishes, we can now preview our site again, and we can see that our images are being sourced from Cloudinary.
Better yet, if we look again at the Network tab, we can see that our images are now being served as AVIF because Chrome supports that format along with smaller sizes!
Step 3: Updating plugin configuration to upload images to Cloudinary
By default, the Cloudinary Build Plugin for Netlify will “fetch” the images from remote locations, including Netlify, and serve it cached and optimized in front.
Alternatively, we can tell Netlify to upload all of those images to Cloudinary, and serve them directly from Cloudinary.
This gives us a few benefits, such as being able to have more control over how we transform our images and how they’re managed.
The best part, setting up our images to be uploaded instead of fetched is a simple config change away!
To do this we have two options: unsigned uploads by providing a Cloudinary Upload Preset or signed uploads by providing our API Key and API Secret.
We’ll walk through adding our API Key and API Secret to maximize our ability to control our images.
Note: if you want to learn how to create an Upload Preset to use unsigned uploads, check out my previous tutorial How to Programmatically Upload Images to Cloudinary in React & Next.js.
To start, we need to add a new input to our Netlify config.
Inside of your
netlify.toml add a
upload so that your config looks like the following:
[[plugins]] package = "netlify-plugin-cloudinary" [plugins.inputs] cloudName = "[Your Cloudinary Cloud Name]" deliveryType = "upload"
Now before you push that up to Git, we have one more step we need to do.
Tip: if you already pushed this up, you can always start a new deployment from the Netlify UI after completing the below.
Next, we want to find our API Key and API Secret, which we’ll set as environment variables inside of Netlify.
You can find your Cloudinary API Key and API Secret in the same place we found our Cloudinary Cloud Name.
We’ll now copy these values over to Netlify.
Inside of Netlify, head over to Site Settings, Build & deploy, and then select Environment where at the top of the Environment section your should see Environment variables.
Here click Edit variables and we’ll want to add two variables with their corresponding values:
Finally, push your local
netlify.toml changes up to Git, which should trigger another new Netlify deploy.
Once complete, we can now see that our images are specifying a delivery type of fetch.
We can also now see that inside of our Cloudinary Media Manager, our images were uploaded to our account!
What else can we do?
Add Cloudinary images to your app with transformations
If you want to dig in and start using Cloudinary closer to your app, you can add a ton of additional features that work on the fly such as automatically cropping images to faces with face detection.
Programmatically upload from a form
Running a website where visitors can sign up and log in often comes with the ability to upload an avatar or upload an image of some sort. We can use a simple form, collect the image with FormData, and upload it straight to Cloudinary with the API.