Trigger a Feedback Form on Video Completion in Nuxtjs

Idris Olubisi

Interactivity is a big part of today's online pages. These responsibilities include gathering information on user involvement, processing form submissions, and controlling the interactivity of media assets.

In this tutorial, we will discuss how to trigger a feedback form on video completion in Nuxt.js.

Sandbox

This project was completed in a Codesandbox. To get started quickly, fork the Codesandbox or run the project.

GitHub Repository: https://github.com/Olanetsoft/video-event-trigger-in-nuxt

Prerequisite

The knowledge of JavaScript and Vue.js is needed for this post. The knowledge of Nuxt.js is not required but preferred.

Getting Started with Nuxtjs

Nuxt.js provides the bedrock of our Vue.js project, providing structure and flexibility while allowing us to scale the application with confidence.

It is extensible, with a robust module ecosystem and hooks engine that makes it simple to integrate your REST or GraphQL endpoints, favourite CMS, CSS frameworks, and other third-party applications.

Project Setup and Installation

To create a new project, we will use the command below to scaffold a new project:

1npx create-nuxt-app <project-name>

A series of prompts will appear as a result of the command. Here are the defaults we recommend:

Next, we need to navigate the project directory and start the development server using the command below.

1cd <project name> && yarn dev

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

Cloudinary Video Player Installation

We need to detect and respond when the status of a video player changes; thus, we will be relying on the Cloudinary Video Player for customization and integration.

Cloudinary video player is a JavaScript-based HTML5 video player that comes with a slew of helpful customization and integration features, as well as monetization and analytics support.

The video player's assets will be added to our nuxt.config.js in the link and script section of the file using the following snippet:

1// nuxt.config.js
2
3 export default {
4 head: {
5 ...
6 link: [
7 ...
8 {
9 rel: 'stylesheet',
10 href: 'https://unpkg.com/cloudinary-video-player@1.5.9/dist/cld-video-player.min.css'
11 }
12 ],
13 script: [
14 {
15 src: 'https://unpkg.com/cloudinary-core@latest/cloudinary-core-shrinkwrap.min.js'
16 },
17 {
18 src: 'https://unpkg.com/cloudinary-video-player@1.5.9/dist/cld-video-player.min.js'
19 },
20 ],
21 },
22 };

We need to save our Cloudinary cloud name to refer to it from any file. In the following step, it will be saved as an environmental variable in the global .env file at the project root.

You can get your cloud name from your Cloudinary dashboard by signing up for a Cloudinary Account.

Create a .env file at the root of the project with the command touch .env and update it with the following snippet:

1NUXT_ENV_CLOUDINARY_CLOUD_NAME=<cloudinary-cloud-name>

We can now create our video player by updating pages/index.vue with the following code snippet:

1<template>
2 <div class="flex justify-center items-center h-screen space-x-10">
3 <div class="rounded overflow-hidden shadow-lg mb-4 content-center">
4 <div class="px-6 py-4 pb-2">
5 <div class="font-bold text-xl mb-2">Feedback Form Trigger</div>
6 <video
7 id="video-player"
8 controls
9 autoplay
10 muted
11 width="500px"
12 class="width-full"
13 ></video>
14 </div>
15 </div>
16 </div>
17 </template>
18
19 <script>
20 export default {
21 data() {
22 return {
23 cld: null,
24 player: null,
25 video: "samples/animals/testvid",
26 };
27 },
28
29 mounted() {
30 this.cld = cloudinary.Cloudinary.new({
31 cloud_name: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,
32 secure: true,
33 });
34
35 this.player = this.cld.videoPlayer("video-player", {
36 analytics: {
37 events: ["ended"],
38 },
39 });
40
41 this.player.source(this.video);
42 },
43 name: "IndexPage",
44 };
45 </script>

In the code snippet above, we established a Cloudinary instance, used it to initialize the video player, and set up the video source in our mounted lifecycle hook.

We should have something similar to the image below:

Trigger a Feedback Form based on Video State

We have successfully integrated our video player, and we can set up a trigger action for when the video has ended. This is accomplished by simply adding the events to the analytics setting in the video player's setup. The video state is then stored in the page’s state with the aid of event listeners.

Next, We will update the pages/index.vue with the code snippet below:

1<template>
2 <!-- markup goes here -->
3 </template>
4
5 <script>
6 export default {
7 data() {
8 return {
9 //...
10 ended: null,
11 };
12 },
13
14 mounted() {
15 //...
16 this.player.on("ended", () => {
17 this.ended = true;
18 });
19 },
20 //...
21 };
22 </script>

In the code snippet above, we created a state variable ended that keeps track of the event whenever our video ends.

Next, we will create a Form.vue file inside the components folder to display our feedback form with the snippet below:

1<template>
2 <form class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
3 <div class="mb-4">
4 <label class="block text-gray-700 text-sm font-bold mb-2" for="name">
5 Name
6 </label>
7 <input
8 class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
9 id="name"
10 type="text"
11 placeholder="name"
12 ref="name"
13 />
14 </div>
15 <div class="mb-6">
16 <label class="block text-gray-700 text-sm font-bold mb-2" for="feedback">
17 Video Feedback
18 </label>
19 <textarea
20 class="
21 form-control
22 block
23 w-full
24 px-3
25 py-1.5
26 text-base
27 font-normal
28 text-gray-700
29 bg-white bg-clip-padding
30 border border-solid border-gray-300
31 rounded
32 transition
33 ease-in-out
34 m-0
35 focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none
36 "
37 id="exampleFormControlTextarea1"
38 rows="3"
39 placeholder="Your message"
40 ></textarea>
41 </div>
42 <div class="flex items-center justify-between">
43 <button
44 class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
45 type="button"
46 @click.prevent="getFormValues()"
47 >
48 Submit
49 </button>
50 </div>
51 </form>
52 </template>
53
54 <script>
55 export default {
56 data() {
57 return {
58 name: "",
59 feedback: "",
60 videoEnded: "",
61 };
62 },
63 methods: {
64 getFormValues() {
65 alert(`Feedback received successfully!`);
66 console.log(this.$refs.name.value);
67 console.log(this.$refs.feedback.value);
68 },
69 },
70 };
71 </script>

Next, we update pages/index.vue by importing the Form.vue component with the following snippet below:

1<template>
2 <div class="flex justify-center items-center h-screen space-x-10">
3 <div class="rounded overflow-hidden shadow-lg mb-4 content-center">
4 <div class="px-6 py-4 pb-2">
5 <div class="font-bold text-xl mb-2">Feedback Form Trigger</div>
6 <video
7 id="video-player"
8 controls
9 autoplay
10 muted
11 width="500px"
12 class="width-full"
13 ></video>
14 </div>
15 </div>
16 <!-- Form Added here -->
17 <Form v-if="ended"></Form>
18 </div>
19 </template>
20
21 <script>
22 import Form from "../components/Form.vue";
23 //...
24 components: {
25 Form,
26 },
27 name: "IndexPage",
28 };
29 </script>

In the snippet above, we use the v-if="ended" attribute in the Form imported to show the feedback form when the ended variable is true.

Next, testing our application by opening a local development server, we should have something similar to what is shown below after the video ends.

Conclusion

This article addressed triggering a feedback form on video Completion in Nuxt.js. Once a video has finished playing, we render a feedback form to receive the user's input/feedback.

Resources

You may find these resources helpful.

Idris Olubisi

Software Engineer & Technical Writer

A Software Engineer & Technical Writer with immense knowledge and a passionate speaker about open source, blockchain, software products, and serverless technologies.