Cloudinary Blog

Applying Awesome Image Effects in Nuxt Applications With Cloudinary

By David Atanda
How to Apply Riveting Image Effects in Nuxt Applications With Cloudinary

Nowadays, no way can we build modern apps for the web without considering visuals, which are one of the most efficient ways of communicating online. However, improvements in image quality over the years have exacted a price in larger files, slowing down page loads, especially in low-bandwidth regions or on mobile devices. To resolve that conundrum, turn to Cloudinary, a platform that offers the infrastructure for managing images in web apps. Additionally, Cloudinary’s reliable APIs serve visuals through multiple, fast content delivery networks (CDNs).

This article describes how to save, display, and transform images in a Nuxt app with Cloudinary. Of remarkable help is Cloudinary’s npm package, which abstracts all the processes in Nuxt. You upload images with this.$cloudinary.uploadand view them with the custom, out-of-the-box component <cld-image/>.

Getting Started With Nuxt

First, integrate Cloudinary with Nuxt by means of a simple project, in which you’ll upload an image to Cloudinary and then transform the image. For the code for a more complex app, check out the CloudyBadge project.

Follow these steps:

  1. Verify if you have installed Node.js on our computer by typing this command on a terminal:

    node -v

    If the output shows that Node.js is not in your computer, download the latest version.

  2. Scaffold a new project called nuxt-cloudinary with this npm command:

    npx create-nuxt-app nuxt-cloudinary

    After a few installations, several prompts are displayed. Pick as many settings as you desire, but be sure to choose Universal (SSG/SSR) for rendering.

    Universal

  3. Go to the nuxt-cloudinary directory with the command cd nuxt-cloudinary and then launch your server by typing npm run dev.

  4. Optional. Clone the project’s complete code on GitHub to your machine. Having a copy of the code handy makes it easier to follow the next steps.

Getting Started With Cloudinary

If you don’t have one yet, sign up for a free Cloudinary account, which offers you credits for transformations, storage, and bandwidth. Alternatively, upgrade to a paid account for more credits and other features.

Installation

Do the following:

  1. Install the @nuxtjs/cloudinary dependency to your Nuxt project. Type:

    npm install @nuxtjs/cloudinarynpm install @nuxtjs/cloudinary

  2. Add @nuxtjs/cloudinary as a module in the modules sections of your nuxt.config.js file:

    Copy to clipboard
    export default {
    modules: [
    '@nuxtjs/cloudinary'
    ]
    }
  3. Create a .env file to hold your three credentials:

    Copy to clipboard
    CLOUDNAME=YOUR_CLOUD_NAME
    API_KEY=YOUR_API_KEY
    API_SECRET=YOUR_API_SECRET

    The credentials’ values are displayed on your Cloudinary dashboard.

  4. Open the nuxt.config.js file, which was generated in your project’s root directory by create-nuxt, and create a Cloudinary object that encompasses the credentials in your .env file:

    Copy to clipboard
    cloudinary: {
    cloudName: process.env.CLOUDNAME,
    apiKey: process.env.API_KEY, 
    apiSecret: process.env.API_SECRET, 
    useComponent: true 
    }

Note
Setting useComponent to true means that you can use the out-of-the-box Vue components with the @nuxtjs/cloudinary library.

Your nuxt.config.js file now reads like this:

Copy to clipboard
export default {
  head: {
    title: 'nuxt-cloudinary',
    htmlAttrs: {
      lang: 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  components: true,
  modules: [
    '@nuxtjs/cloudinary'
  ],
  // Build configuration: https://go.nuxtjs.dev/config-build.
  build: {
  },
  cloudinary: {
    cloudName: process.env.CLOUDNAME,
    apiKey: process.env.API_KEY, //Needed only if you are using server-side upload.
    apiSecret: process.env.API_SECRET, //Needed only if you are using server-side upload.
    useComponent: true //Use Vue components.
  }
}

Creation of an Upload Preset

Upload preset is a default behavior that reduces repetition on upload requests through saved settings. You can set up multiple presets.

To create an upload preset:

  1. Click the Upload tab near the top of your Cloudinary settings page.

    Under Upload presets, two modes are displayed: unsigned and signed. A signed upload preset applies to secured (server-side) uploads; an unsigned one, browser (client-side) uploads. Upload preset

  2. Note the name of the unsigned upload preset, which you’ll need later for client-side uploads.

Image Uploads

To upload images to Cloudinary:

  1. Go to your component (pages/index.vue) and add the <input/> element that uploads files.

    Copy to clipboard
    <input
    id="file-input"
    type="file"
    ref="fileInput"
    accept="image/*"
    @change="onFilePicked"
    required
    />

    @change triggers the onFilePicked function when you select an image; ref gets data from <input/>.

  2. Add data to your components to manage their state.

    Copy to clipboard
    data() {
    return {
    formData: {
      imageName: "",
      imageUrl: ''
    }
    }
    };

You store the image name and URL before uploading the image. When you attach the image, onFilePicked sends the name and the image in Base64 format to Cloudinary through the FileReader Web API.

Copy to clipboard
methods: {
  onFilePicked(event) {
    const files = event.target.files;
    const fileReader = new FileReader();
    fileReader.addEventListener("load", () => {
      this.formData.imageUrl = fileReader.result;
      console.log(this.formData.imageUrl)
    });
    fileReader.readAsDataURL(files[0]);
    const fileName = this.$refs.fileInput.value;
    this.formData.imageName = fileName.split("\\").pop().replace(/\.[^/.]+$/, "");
  }
}

Create a button to trigger the function that initiates the upload:

<button @click="cloudinary">Upload</button>

Within that function is this.$cloudinary.upload, which is available globally through the library you installed.

Copy to clipboard
methods: {
  cloudinary() {
    this.$cloudinary
      .upload(this.formData.imageUrl, {
        public_id: this.formData.imageName,
        folder: "content",
        upload_preset: "your-preset-name"
      })
      .then(res => console.log(res))
      .catch(err => cosole.log(err));
  },
}

You’re sending the image in Base64 format in this.formData.imageUrl. The public ID (as denoted by public_id) represents the image name. The folder takes the name of the Cloudinary folder where you save the image, and then you add the name of the upload preset you created earlier.

Here’s an example of the response, which contains all the relevant information, including a link to the image hosted on Cloudinary, the image format, and the public ID:

Copy to clipboard
{
  access_mode: "public"
  asset_id: "952a355221ce840b1f4fcd91b93a2021"
  bytes: 12701
  created_at: "2021-10-07T07:55:48Z"
  etag: "1bd19b75a275ee715b1130e72ba6e985"
  existing: false
  format: "png"
  height: 1080
  placeholder: false
  public_id: "content/Bmvp (1)"
  resource_type: "image"
  secure_url: "https://res.cloudinary.com/dfkuxnesz/image/upload/v1633593348/content/Bmvp%20%281%29.png"
  signature: "d74486803815e872ca92ddabbc361351ad13ea83"
  tags: []
  type: "upload"
  url: "http://res.cloudinary.com/dfkuxnesz/image/upload/v1633593348/content/Bmvp%20%281%29.png"
  version: 1633593348
  version_id: "6b3e6b601197ac0ba28bc9da5a377b16"
  width: 1080
}

Display of Cloudinary Images Through Vue Components

Now display the uploaded image with the Vue component <cld-image/>, which requires a few parameters, including the public ID you received after uploading the image.

Copy to clipboard
<cld-image
  public-id="your-public-image-id"
  width="200"
  crop="scale"
  fetchFormat="auto"
  quality="auto"
  loading="lazy"
/>

Be sure to replace your-public-image-id with your image's public ID. The image then shows up in your app, as in this example in the case of two uploaded images:

Nuxt app

Image Transformation

Suppose you want to automatically create a circular image centered on each person's face in the above example. That would normally be tough to do in the browser, but not with Cloudinary. Simply transform the images with <cld-transformation/>, like this:

Copy to clipboard
<cld-image
  public-id="/content/woman"
  fetchFormat="auto"
  quality="auto"
  loading="lazy"
>
  <cld-transformation
    width="200"
    height="200"
    gravity="face"
    crop="fill"
    radius="max"
  />
</cld-image>

Here, you set the width and height to 200, resize the image around each person's face with crop, and round off the image border by setting the radius to the maximum. The two transformed images look like this:

Circle profile

Easy, right? The nice circular headshots are now ready for display on a profile page. You could also feature them on physical assets like conference badges and ID cards.

The complete code repository is on GitHub.

Taking Off With Cloudinary

Cloudinary offers numerous valuable ways for managing images in apps at scale, enabling you to generate smaller yet high-quality images, correspondingly enhancing page performance. Additionally, other Vue components, including <cld-video/> for managing videos, are available from Cloudinary.

All those features are especially helpful for creating social-media apps or photo-management systems, or for scaling side projects. An example: Build a fun photo-management app with Nuxt so that your users can upload pictures to one handy location. Afterwards, the app can edit the pictures with Cloudinary’s image-transformation capabilities for a similar look and a consistent user experience.

Cloudinary is also a big boon for authentication apps, e.g., you can upload profile photos and store their URLs in a database for later use, or pull those photos with the Vue component and set their radius, center them, and round off the border for an appealing look.

Let your imagination fly! Build a fun Nuxt app or spiff up an existing one. As a start, register for a free Cloudinary account and explore the platform’s site for details on how to forge impressive image effects.

About the Author

David Atanda is a front-end developer and technical writer dedicated to making the web more accessible while building scalable and high-performance web applications.

Recent Blog Posts

Our $2B Valuation

By
Blackstone Growth Invests in Cloudinary

When we started our journey in 2012, we were looking to improve our lives as developers by making it easier for us to handle the arduous tasks of handling images and videos in our code. That initial line of developer code has evolved into a full suite of media experience solutions driven by a mission that gradually revealed itself over the course of the past 10 years: help companies unleash the full potential of their media to create the most engaging visual experiences.

Read more
Direct-to-Consumer E-Commerce Requires Compelling Visual Experiences

When brands like you adopt a direct–to-consumer (DTC) e-commerce approach with no involvement of retailers or marketplaces, you gain direct and timely insight into evolving shopping behaviors. Accordingly, you can accommodate shoppers’ preferences by continually adjusting your product offering and interspersing the shopping journey with moments of excitement and intrigue. Opportunities abound for you to cultivate engaging customer relationships.

Read more
Automatically Translating Videos for an International Audience

No matter your business focus—public service, B2B integration, recruitment—multimedia, in particular video, is remarkably effective in communicating with the audience. Before, making video accessible to diverse viewers involved tasks galore, such as eliciting the service of production studios to manually dub, transcribe, and add subtitles. Those operations were costly and slow, especially for globally destined content.

Read more
Cloudinary Helps Minted Manage Its Image-Generation Pipeline at Scale

Shoppers return time and again to Minted’s global online community of independent artists and designers because they know they can count on unique, statement-making products of the highest quality there. Concurrently, the visual imagery on Minted.com must do justice to the designs into which the creators have poured their hearts and souls. For Minted’s VP of Engineering David Lien, “Because we are a premium brand, we need to ensure that every single one of our product images matches the selected configuration exactly. For example, if you pick an 18x24 art print on blue canvas, we will show that exact combination on the hero images in the PDF.”

Read more
Highlights on ImageCon 2021 and a Preview of ImageCon 2022

New year, same trend! Visual media will continue to play a monumental role in driving online conversions. To keep up with visual-experience trends and best practices, Cloudinary holds an annual conference called ImageCon, a one-of-a-kind event that helps attendees create the most engaging visual experiences possible.

Read more