Optimize and Deliver Hosted Images in NuxtJS

Banner for a MediaJam post

Tosin Moronfolu

Introduction

Images are an essential part of a web application. Most times, there is a need to transform, optimize, and deliver a version of an image. Often, these images are hosted on a remote server which aids reusability.

This article will look at how to fetch, transform, and optimize hosted images in Nuxt.js using Cloudinary.

Prerequisites

Understanding this article requires the following:

  • Installation of Node.js
  • Basic knowledge of JavaScript
  • Familiarity with Nuxt.js
  • A Cloudinary account (sign up for a free account here).

Repository

This article's source code is available on GitHub:

https://github.com/folucode/nuxtjs-image-optimizations

Sandbox

The completed project is on CodeSandbox. Fork it and run the code.

Creating a Nuxt.js Project

Use npx create-nuxt-app <project-name> to create a new Nuxt.js project. The process of scaffolding the project would provide a list of options, which should look like this:

After successful project creation, we will navigate into our directory and start our application by running the following command:

1$ cd <project name>
2$ npm run dev

Nuxt.js will, in turn, start a hot-reloading development environment that is accessible by default at http://localhost:3000.

Allow Image Fetching on Cloudinary

To fetch images using our Cloudinary account, we ensure that fetched URLs are unrestricted by unchecking the Fetched URL box in the Restricted media types section of the Security tab in our Cloudinary account settings.

Allow fetched images setting

Configuring Cloudinary

To use Cloudinary in our Nuxt.js application, we will need to install the Cloudinary Nuxt SDK in our project.

1npm install @nuxtjs/cloudinary

Configuring nuxt.config for Cloudinary

We need to configure our Nuxt.js application in the nuxt.config file before we can use Cloudinary.

To do this, we will need to perform the following steps:

  1. Create a .env file in the root of our Nuxt.js project and add our Cloudinary Cloud name***.*** We can find this by navigating to the Cloudinary dashboard.
  2. Register the property in our .env file like so:
1cloudName='***'
  1. Register the Cloudinary component for global use in the nuxt.config.js file by adding '@nuxtjs/cloudinary' in the modules section:
1modules: [ '@nuxtjs/cloudinary' ],
  1. Add a cloudinary section in the nuxt.config.js like so:
1cloudinary: {
2 cloudName: process.env.cloudName, /sandbox/pages/index.vue
3 useComponent: true,
4},

The useComponent attribute is needed to make Cloudinary components like the cldimage and cldtransformation available in Nuxt.js.

N**ote: *Replace all occurrences of “**" with the correct values.

Using Fetch URL

We will use the fetch-url feature provided by Cloudinary to deliver the hosted image. In the components folder, we create a new file called Car.vue and add the following code to display the hosted image.

This is the image we would be using: https://cdn.luxe.digital/media/20220127155206/fastest-cars-world-2022-luxe-digital-1-1200x600.jpg.webp.

1<template>
2 <div>
3 <cld-image
4 :public-id="publicId"
5 type="fetch"
6 alt="An image of a car"
7 height="400"
8 width="700"
9 >
10 </cld-image>
11 </div>
12</template>
13
14<script>
15export default {
16 data() {
17 return {
18 publicId:
19 "https://cdn.luxe.digital/media/20220127155206/fastest-cars-world-2022-luxe-digital-1-1200x600.jpg.webp",
20 };
21 },
22};
23</script>

The above code snippet uses Cloudinary's cld-image component to display our image and takes several attributes. Since we're delivering a hosted image, we set the type to 'fetch.'

We should see the image below in our browser:

Applying Transformations to a Hosted Image

We want to add transformations to the image we just delivered. In the Car.vue file, in-between the cld-image tag, add the following code snippet:

1<template>
2 ...
3 <cld-transformation radius="80" />
4 <cld-transformation effect="grayscale" />
5 <cld-transformation
6 overlay="text:arial_60:Rimac Nevera C Two"
7 gravity="south"
8 y="20"
9 />
10 ...
11</template>

The code above rounds the corners of the image, applies a grayscale effect and adds text to the bottom of the resized image.

The resulting image in our browser should look like this:

Applying Optimizations to a Hosted Image

Similar to the image transformation steps, we will add optimization effects to an image.

To do this, let’s create a new file in the components folder called BeachHut.vue and then add the code below to it:

1<template>
2 <div>
3 <cld-image
4 :public-id="publicId"
5 type="fetch"
6 alt="An image of a cat"
7 height="400"
8 width="700"
9 >
10 <cld-transformation effect="vectorize" />
11 <cld-transformation format="auto" />
12 <cld-transformation quality="100" />
13 </cld-image>
14 </div>
15</template>
16<script>
17export default {
18 data() {
19 return {
20 publicId: "https://res.cloudinary.com/demo/image/upload/beach_huts.jpg",
21 };
22 },
23};
24</script>

And then update the index.vue file to accommodate the BeachHut component like so:

1<template>
2 <div>
3 <Car />
4 <BeachHut />
5 </div>
6</template>
7
8<script>
9import Car from "../components/Car.vue";
10import BeachHut from "../components/BeachHut.vue";
11
12export default {
13 name: "IndexPage",
14 components: { Car, BeachHut },
15};
16</script>

The original looks likes this:

The resulting image after applying the optimization should look like this:

Conclusion

This article discussed transforming and optimizing images by applying Cloudinary transformation and optimization parameters.

Further Reading

1- [Cloudinary VueJS documentation](https://cloudinary.com/documentation/vue_integration)
2- [Image transformations](https://cloudinary.com/documentation/vue_image_manipulation)
3- [Cloudinary NuxtJS documentation](https://cloudinary.nuxtjs.org/)

Tosin Moronfolu

Software Engineer

I'm a software engineer with hands-on experience in building robust and complex applications improving performance and scalability. I love everything tech and science, especially physics and maths. I also love to read books, mainly non-fiction, and I love music; I play the guitar.