Create Custom Summer Concert Tickets in NuxtJS

Moronfolu Olufunke

Concerts are music performances done by one or more musicians and often happen a lot in the summer due to the warm weather that facilitates a lot of outdoor gatherings. Tickets for such events have gone through several transformations; from the age of manual writing with pen on paper to the printing press era to becoming entirely digitized.

This article will discuss creating custom summer concert tickets using Nuxt.js and Cloudinary. After reading this article, we'll have learned how to create custom concert tickets in Nuxt.js using images stored in Cloudinary by 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.

SandBox

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

Github

Check out the complete source code here.

Prerequisites

Understanding this article requires the following:

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

Creating a Nuxt 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'll navigate into our directory and start our application by running the following command:

1cd <project name>
2npm run dev

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

Configuring Cloudinary

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

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, 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:

1cloudName='***'
2apiKey='***'
3apiSecret='***'
  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,
3 apiKey: process.env.apiKey,
4 apiSecret: process.env.apiSecret,
5 useComponent: true,
6},

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

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

Image Upload to Cloudinary

With our Nuxt.js 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 to pick each uploaded image from Cloudinary.

Setting up the Image Store

We will create a utils/ticket.json file which will hold the Cloudinary individual image information for each image occurrence in our application. A sample snippet of our ticket.json file should look like this:

1[
2 {
3 "id": 1,
4 "publicId": "adrian-n-unsplash"
5 }
6]

Creating the Concert Ticket

In creating the concert ticket, we will need to set up the markup, including Cloudinary’s cld-image and cld-transformation component, 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 below:

https://gist.github.com/MoeRayo/ed2ab83e1ed3aa03e101f49ed85c802a

We achieved the following in the code snippet above:

  • Imported the ticket 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 concert’s title and artist’s name
  • Added an error message to prompt users to select an image and fill 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:

Generating the concert ticket

To generate a concert ticket, we'll create a component that renders the generated concert ticket when the handleSubmit function linked to the “Generate Ticket” button is clicked.

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

1<template>
2 <div>
3
4 <cld-image ref="ref" :public-id="publicId">
5
6 <cld-transformation effect="blur:150"/>
7 <cld-transformation effect="brightness_hsb:-30"/>
8 <cld-transformation :overlay="{fontFamily: 'Metal Mania', fontSize: 60, fontWeight: 'bold', text: concertName, testAlign: 'center'}" color="#fff" opacity="90" crop="fit" width="550" effect="shadow"/>
9 <cld-transformation flags="layer_apply"/>
10 <cld-transformation :overlay="{fontFamily: 'Courgette', fontSize: 15, fontWeight: 'bold', text: `Artist: ${artist}`}" color="#fff" effect="shadow" crop="fit" width="120" />
11 <cld-transformation flags="layer_apply" gravity="south_east" x="150" y="80" />
12
13 </cld-image>
14 </div>
15</template>
16<script>
17export default {
18 props: {
19 concertName: {
20 type: String,
21 required: true
22 },
23 artist: {
24 type: String,
25 required: true
26 },
27 publicId: {
28 type: String,
29 required: true
30 },
31 },
32}
33</script>

We achieved the following using the snippet above:

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

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

https://gist.github.com/MoeRayo/428a0ab260f1b477c8f68dda2928b1a6

The handleSubmit method verifies whether an image is selected and if the concert title and artists were added before conditionally rendering the GeneratedConcertTicket.vue component with the expected props.

At this stage, our application should look like this.

Creating a Shareable Link

To share the generated ticket, we will modify the GeneratedConcertTicket.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/GeneratedConcertTicket.vue.

1<template>
2<div>
3
4 <cld-image ref="ref" :public-id="publicId">
5
6 <cld-transformation effect="blur:150"/>
7 <cld-transformation effect="brightness_hsb:-30"/>
8 <cld-transformation :overlay="{fontFamily: 'Metal Mania', fontSize: 60, fontWeight: 'bold', text: concertName, testAlign: 'center'}" color="#fff" opacity="90" crop="fit" width="550" effect="shadow"/>
9 <cld-transformation flags="layer_apply"/>
10 <cld-transformation :overlay="{fontFamily: 'Courgette', fontSize: 15, fontWeight: 'bold', text: `Artist: ${artist}`}" color="#fff" effect="shadow" crop="fit" width="120" />
11 <cld-transformation flags="layer_apply" gravity="south_east" x="150" y="80" />
12
13 </cld-image>
14 <div class="mv4">
15 <label class="db mb2 f3 fw4 b">Shareable link</label>
16 <input disabled type="text" class="db w-90 pv3 ph2 br2 ba b--black-40 f7" :value="url" />
17 <button class="f6 link dim br2 ph3 pv2 db white bg-dark-green ba b--green mt2" @click="copyUrl">{{share}}</button>
18 </div>
19
20</div>
21</template>
22<script>
23export default {
24props: {
25 concertName: {
26 type: String,
27 required: true
28 },
29 artist: {
30 type: String,
31 required: true
32 },
33 publicId: {
34 type: String,
35 required: true
36 },
37},
38data() {
39 return {
40 url: "",
41 share: 'Share Link'
42 };
43},
44mounted() {
45 this.$nextTick(() => {
46 this.url = this.$refs.ref.$el.src
47 });
48},
49methods: {
50 copyUrl(){
51 navigator.clipboard
52 .writeText(this.url)
53 .then(() => (this.share = 'Copied!'))
54 .catch((err) => err)
55 }
56},
57}
58</script>

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:

Click here to find the shareable link from the generated concert ticket.

Conclusion

This post explains creating a custom summer concert ticket using Nuxt.js and Cloudinary transformations.

Resources

Moronfolu Olufunke

Frontend Engineer | Tecnical Writer | Story Teller

Olufunke is a Frontend Engineer and technical writer who enjoys building stuff and writing about them.