Skip to content

RESOURCES / BLOG

Create a Custom Meetup Banner in NuxtJS

A meetup is a form of informal gathering between people who share common interests or hobbies. Creating a banner for meetups can be a daunting task, and in this article, we’ll discuss how to generate a custom meetup banner.

To build this banner, we will be using Nuxt.js and Cloudinary. After reading this article, you’ll have learned how to create a meetup banner using images stored in Cloudinary while applying Cloudinary transformations.

Nuxt.js is a Vue.js-based, open-source JavaScript library that improves building server-rendered Vue.js applications, leading to more performant web applications.

Cloudinary is a cloud-based video and image management platform that offers services for managing and transforming uploaded assets for usage on the web.

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

Check out the complete source code here.

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!

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

create a Nuxt project

After successful project creation, we’ll navigate into our directory and start our application by running the following commands.

cd <project name>
npm run dev
Code language: HTML, XML (xml)

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

To use Cloudinary, we will need to create an account and also install the Cloudinary Nuxt SDK in our project, like so:

npm install @nuxtjs/cloudinary
Code language: CSS (css)

We need to configure our Nuxt 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 project and add our Cloudinary Cloudname, API Key, and the API Secret. We can find these by navigating to the Cloudinary dashboard.
  2. Register these properties in our .env file like so:
cloudName='***'
apiKey='***'
apiSecret='***'   
Code language: JavaScript (javascript)
  1. Register the Cloudinary component for global use in the nuxt.config file by adding '@nuxtjs/cloudinary' in the modules section
  2. Add a cloudinary section in the nuxt.config like so:
cloudinary: {
  cloudName: process.env.cloudName,
  apiKey: process.env.apiKey,
  apiSecret: process.env.apiSecret,
  useComponent: true,
}
Code language: CSS (css)

NB: Endeavor to replace all occurrences of “**” with the correct values.

With our Nuxt app scaffolding completed, we’ll upload images from Unsplash to Cloudinary.

Cloudinary allows us to upload images via the dashboard by clicking the Media Library tab.

After uploading the images, we will need to copy the public Id. This is required to pick each uploaded image from Cloudinary.

Uploaded image on Cloudinary

We will need to call our images from the Nuxt application by creating a utils folder at the root of our application. We will then create a banner.json file within this folder to hold the individual image information for each image occurrence in our application.

A sample snippet of our banner.json file should look like this:

[
  {
    "id": 1,
    "publicId": "s-o-c-i-a-l-c-u-t-unsplash"
  },
]
Code language: JSON / JSON with Comments (json)

In creating the meetup banner, we will need to set up the markup, including Cloudinary’s cld-image and cld-transformation components, which can be likened to using the native <img> tag in an HTML document.

To achieve this, we will navigate to the pages/index.vue file and replace the content with the code from the link below:

https://gist.github.com/MoeRayo/0817c53d64a2cfddff836daaa6fd52d5

We achieved the following in the code snippet above:

  • Imported the banner JSON images from the utils folder and declared it in the data properties before using Cloudinary images components — <cld-image /> and <cld-transformation /> – to render the images in the application.
  • Added a click function to the images rendered to show the active image.
  • Created a functional form to handle user input for the event title, details, and speakers.
  • Added an error message to prompt users to select an image and complete the input fields before submission.
  • Added a data property to manage the form data, error message, and other vital properties.

After this stage, our page should look like the image below:

We’ll create a component that renders the generated banner when the handleSubmit function linked to the “Generate Banner” button is clicked to generate a custom banner.

We will create a GeneratedBanner.vue file in the components folder and add the code below to the file.

<template>
  <div>
    <cld-image ref="ref" :public-id="publicId">
    
      <cld-transformation effect="blur:300"/>
      
      <cld-transformation :overlay="{fontFamily: 'Berkshire Swash', fontSize: 40, fontWeight: 'bold', text: title}" color="#fff" opacity="90" crop="fit" width="400" background="#000" x="-80" effect="shadow" y="-60"/>
      
      <cld-transformation :overlay="{fontFamily: 'Lustria', fontSize: 16, fontWeight: '', text: description}" color="#000" crop="fit" width="190" x="-200" y="35"/>
      
      <cld-transformation :overlay="{fontFamily: 'Lustria', fontSize: 15, fontWeight: 'bold', text: `Speakers: ${speakers}`}" color="#fff" effect="shadow"  crop="fit" width="120" background="#000" x="200" y="130"/>
      
    </cld-image>
  </div>
</template>
<script>
  export default {
    props: {
      title: { 
        type: String, 
        required: true 
      },
      description: { 
        type: String, 
        required: true 
      },
      speakers: { 
        type: String, 
        required: true
      },
      publicId: { 
        type: String, 
        required: true
      },
    },
  }
</script>
Code language: HTML, XML (xml)

We achieved the following using the snippet above:

  • Rendered the generated banner using Cloudinary’s <cld-image /> and <cld-transformation />.
  • Configured the Cloudinary components to accept the title, description, speakers, and publicId as props.
  • Cloudinary components support assets transformations, which we leveraged by blurring, changing the width, and cropping images. We also added text transformations like the font family and colours to achieve the desired banner image.

To render the GeneratedBanner.vue component, in our view, we will need to import it into the index.vue file where it is conditionally rendered. Like so:

https://gist.github.com/MoeRayo/1cbd5447dd3eb7968602d4e46242a02b

The handleSubmit method from the snippet above verifies whether an image is selected and if the title and speakers were added before conditionally rendering the GeneratedBanner component with the expected props.

At this stage, our application should look like this.

Sharing the generated banner is just as important as the banner creation process. To share our banner, we will modify the GeneratedBanner.vue component by adding functionality to create the image URL and a button that enables us to copy the URL.

Thus, we’ll add the following code in the components/GeneratedBanner.vue.

<template>
  <div>
    <cld-image ref="ref" :public-id="publicId">
      <!-- Cloudinary image transformation code -->
    </cld-image>
    
    <!-- Add the shareable link functionality -->
    <div class="mv4 dn">
      <label class="db mb2 f3 fw4 b">Shareable link</label>
      <input disabled type="text" class="db w-90 pv3 ph2 br2 ba b--black-40 f7" :value="url" />
      <button class="f6 link dim br2 ph3 pv2 db white bg-dark-green ba b--green mt2" @click="copyUrl">{{share}}</button>
    </div>

  </div>
</template>
<script>
  export default {
    props: {
      // props
    },
    data() {
      return {
        url: "",
        share: 'Share Link'
      };
    },
    mounted() {
      this.$nextTick(() => {
        this.url = this.$refs.ref.$el.src
      });
    },
    methods: {
      copyUrl(){
        navigator.clipboard
        .writeText(this.url)
        .then(() => (this.share = 'Copied!'))
        .catch((err) => err)
      }
    }
  }
</script>    
    
Code language: HTML, XML (xml)

The code block above does the following:

  • Adds a ref attribute to the cld-image component to access the src attribute of the rendered image in the DOM.
  • Creates a url in the data options, which is initialized to “empty” but gets updated with the image src value when the component is mounted.
  • Added a copyUrl method that copies the updated URL to the clipboard for easy sharing.

Our application, at this stage, should look like this:

Completed application

Click here to find the shareable link from the generated banner.

This post explains creating a custom meetup banner using Nuxt.js and Cloudinary transformations.

Start Using Cloudinary

Sign up for our free plan and start creating stunning visual experiences in minutes.

Sign Up for Free