Adding Shoppable Videos to Your NuxtJS Website

Eugene Musebe

As e-commerce and video consumption adoption rises, an intersection of the two is emerging. Giving users an in-depth experience of the product by displaying not just static images but a sample usage video. These are called Shoppable videos. Let us learn how we can add them to our Nuxt.Js websites.

Codesandbox

The final project can be viewed on Codesandbox.

You can find the full source code on my Github repository.

App Setup

Our first step is to set up our Nuxt.Js app. Nuxt.Js is a Vue.Js framework that boasts of improving developer experience while being performant. To get started, ensure you have yarn or npm v5.2+/v6.1+ installed. Open your terminal in your preferred working directory and run the following command.

1yarn create nuxt-app nuxtjs-shoppable-video
2
3# OR
4
5npx create-nuxt-app nuxtjs-shoppable-video
6
7# OR
8
9npm init nuxt-app nuxtjs-shoppable-video

Once you run the above command, you will receive a set of setup questions. Here are our recommended defaults:

Project name: nuxtjs-shoppable-video

Programming language: JavaScript

Package manager: Yarn

UI framework: Tailwind CSS

Nuxt.js modules: N/A

Linting tools: N/A

Testing framework: None

Rendering mode: Universal (SSR/SSG)

Deployment target: Server (Node.js hosting)

Development tools: None

Once the setup process is complete, you may now enter the directory and run the project.

1cd nuxtjs-shoppable-video
2
3
4
5yarn dev
6
7# OR
8
9npm run dev

The project should now be running on http://localhost:3000

Video and image storage

We need to store our media assets before we start consuming them. For this, we will use Cloudinary, a media management platform with a set of rich APIs and SDKs. Open your media library and create a folder called nuxtjs-shoppable-video. If you do not have an account create one here.

Inside this folder add the following files:

You should now have a folder visually similar to this one.

Video player setup

To be able to use advanced video player features such as shoppable video, we will be using Cloudinary's video player. To set it up, you simply need to add its CSS and JavaScript files to your project. We will do this by using the files already hosted on UNPKG's Content Delivery Network (CDN).

To add the files, add the following in the head section of our nuxt.config.js file.

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

With the above setup, our assets will be included on every page in our app. Now we need to configure our Cloudinary cloud name globally. This will link the app to our Cloudinary account. We will store this in our environmental variables as it changes based on who is deploying the code thus we do not want it fixed in our codebase and sent to the remote code repository.

We store environmental variables in the global .env file so if you do not have one feel free to create it.

1touch .env

We can now add our cloud name. If you do not have yours you can refer to the Account Details section of the dashboard.

1<!-- .env -->
2
3NUXT_ENV_CLOUDINARY_CLOUD_NAME=

Video player usage

To use the video player, we need to set up the HTML video element it is going to be running in. We need to give this element cld-video-player cld-video-player-skin-dark classes. We will also give the video player an ID we will use to refer to it later.

1<!-- pages/index.vue -->
2
3<template>
4
5<div>
6
7<video
8
9id="video-player"
10
11controls
12
13muted
14
15class="cld-video-player cld-video-player-skin-dark"
16
17>
18
19</video>
20
21</div>
22
23</template>

Once the above is configured, we now need to instantiate the player in JavaScript and inject the source video to be played.

1// pages/index.vue
2
3<script>
4
5export default {
6
7name: 'IndexPage',
8
9data(){
10
11return {
12
13cld:null,
14
15player:null,
16
17};
18
19},
20
21mounted(){
22
23this.cld = cloudinary.Cloudinary.new({ cloud_name: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME });
24
25this.player = this.cld.videoPlayer('video-player');
26
27this.player.source(
28
29"nuxtjs-shoppable-video/video.mp4",
30
31);
32
33}
34
35}
36
37</script>

We will now have a fully functional video player.

Making the video shoppable

To make a video shoppable, we need to add a shoppable object to the source. This object will have the shoppable video configuration, mainly the UI and functionality as well as the products.

The products array in the object will contain a list of products available in the video. For each product, we specify an id, name, start and end time, image publicId, hotspots where the product is found in the video, hover behaviors, and callback when the product is clicked.

Let us store our shoppable configuration in the data section.

1// pages/index.vue
2
3<script>
4
5export default {
6
7name: 'IndexPage',
8
9data(){
10
11return {
12
13cld:null,
14
15player:null,
16
17shoppable:{
18
19transformation: {
20
21crop: "pad",
22
23aspect_ratio: "1"
24
25},
26
27products: [
28
29{
30
31productId: 1,
32
33productName: "Macbook Pro",
34
35startTime: 0,
36
37endTime: 1,
38
39publicId:
40
41"nuxtjs-shoppable-video/macbook",
42
43hotspots: [
44
45{
46
47time: "00:02",
48
49x: "62%",
50
51y: "32%",
52
53tooltipPosition: "left",
54
55clickUrl: "https://www.amazon.com/Apple-MacBook-Air-Retina-Display/dp/B08VF621Z4/ref=sr_1_2"
56
57}
58
59],
60
61onHover: {
62
63action: "overlay",
64
65args: "See the MacBook in the video"
66
67},
68
69onClick: {
70
71action: "seek",
72
73pause: 5,
74
75args: {
76
77time: "00:02"
78
79}
80
81}
82
83},
84
85{
86
87productId: 2,
88
89productName: "iPad Pro",
90
91startTime: 0,
92
93endTime: 1,
94
95publicId:
96
97"nuxtjs-shoppable-video/ipad",
98
99hotspots: [
100
101{
102
103time: "00:02",
104
105x: "55%",
106
107y: "68%",
108
109tooltipPosition: "left",
110
111clickUrl: "https://www.amazon.com/Apple-12-9-inch-Wi%E2%80%91Fi-Cellular-256GB/dp/B0932BB1BX/ref=sr_1_3"
112
113}
114
115],
116
117onHover: {
118
119action: "overlay",
120
121args: "See the iPad in the video"
122
123},
124
125onClick: {
126
127action: "seek",
128
129pause: 5,
130
131args: {
132
133time: "00:02"
134
135}
136
137}
138
139},
140
141{
142
143productId: 3,
144
145productName: "iPhone",
146
147startTime: 0,
148
149endTime: 1,
150
151publicId:
152
153"nuxtjs-shoppable-video/iphone",
154
155hotspots: [
156
157{
158
159time: "00:02",
160
161x: "35%",
162
163y: "68%",
164
165tooltipPosition: "left",
166
167clickUrl: "https://www.amazon.com/Apple-iPhone-12-Pro-Max/dp/B09JFS16CP/ref=sr_1_1"
168
169}
170
171],
172
173onHover: {
174
175action: "overlay",
176
177args: "See the iPhone in the video"
178
179},
180
181onClick: {
182
183action: "seek",
184
185pause: 5,
186
187args: {
188
189time: "00:02"
190
191}
192
193}
194
195},
196
197]
198
199}
200
201};
202
203},
204
205...
206
207};
208
209</script>

We can now add the shoppable configuration to our player.source statement.

1// pages/index.vue
2
3export default {
4
5...
6
7mounted(){
8
9this.cld = cloudinary.Cloudinary.new({ cloud_name: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME });
10
11
12
13this.player = this.cld.videoPlayer('video-player');
14
15
16
17this.player.source(
18
19"nuxtjs-shoppable-video/video.mp4",
20
21{
22
23shoppable: this.shoppable
24
25}
26
27);
28
29}
30
31}
32
33</script>

This ensures that the video player will use the configuration as the video source is being loaded. Let us see the result.

This is just an introduction to see what we can achieve with shoppable videos using Cloudinary's video player. To see what more is possible, refer to the documentation here.

Eugene Musebe

Software Developer

I’m a full-stack software developer, content creator, and tech community builder based in Nairobi, Kenya. I am addicted to learning new technologies and loves working with like-minded people.