Uniform how-to/Creating shoppable video with Cloudinary, BigCommerce, and Uniform
12 min read
Creating shoppable video with Cloudinary, BigCommerce, and Uniform
Introduction
Shoppable videos, which keep visitors at e-commerce stores engaged, are a great way to enhance the purchasing experience and boost sales. This tutorial steps you through the process of creating a shoppable video with Cloudinary, BigCommerce, and Uniform.
Discerning the technologies
Cloudinary is an image-and video-management service through which you can upload, optimize, transform, and deliver media assets on the web.
BigCommerce is an e-commerce platform for selling both physical and digital merchandise.
Uniform offers digital-experience composition features with which you can create, deliver, and manage building blocks for apps. Instead of making multiple API requests, you can employ Jamstack technologies, such as headless CMSes, commerce APIs, and CDNs, delivering digital experiences as a single source of truth.
Leveraging StackBlitz and GitHub
You’ll work through this tutorial in StackBlitz. Fork it over with this codeline:
1<iframe src="https://stackblitz.com/edit/github-anehxu?embed=1&file=app.vue"></iframe
The source code is available on GitHub.
Understanding the prerequisites
This tutorial requires —
- A basic understanding of React and Next.js
- A Cloudinary account, a Uniform account, and a BigCommerce account, all of which you can create for free.
Getting started
- Create a Next.js project by running this command in your terminal:
1npx create-next-app uniform-shoppabl
- Navigate to the project directory and run the application:
1cd uniform-shoppabl
- Install the Uniform and Cloudinary libraries you’ll need later:
1npm i cloudinary-video-player @uniformdev/canvas @uniformdev/canvas-bigcommerce @uniformdev/canvas-cloudinary @uniformdev/canvas-reac
- Run this command to start the application:
1npm run de
Uploading video to Cloudinary
Upload this video to your Cloudinary account by clicking the Media Library tab at the top of your Cloudinary account’s dashboard and uploading the video to a folder of your choice.
Configuring BigCommerce
Uploading product data to BigCommerce
Your new BigCommerce account comes with dummy product data. For this tutorial, update the inventory with three products of your choice:
Product Name | Default Price | Weight |
---|---|---|
Product 1 | 450 | 2 |
Product 2 | 270 | 2 |
Product 3 | 270 | 2 |
To do that, click Add in the Products menu on the sidebar, input the product name, default price, and weight for each of the three products in the appropriate text fields. Click Save.
Creating an API account
Create an API account through which third-party applications can access your products. Follow the steps below:
- In the main menu, click Settings, scroll to the API section, and click API accounts.
- Click Create API Account and type the account name in the appropriate text field.
- Scroll down to the Products section and set API permissions to read-only.
- Create an .env file in the root of the Next.js application and add the store hash and BigCommerce API token to that file.For the value of the store hash, look under API path for the string after https://api.bigcommerce.com/store. Copy and paste that string after
1BIGCOMMERCE_STORE_HASH=your-store-hash-here 2BIGCOMMERCE_API_TOKEN=your-token-here
BIGCOMMERCE_STORE_HASH=Click to copy
in the.envClick to copy
file. - Click Save. A dialog box with the access token and other credentials then pops up.
- Copy the access token and paste it under
BIGCOMMERCE_API_TOKEN=Click to copy
in the.envClick to copy
file.
Integrating BigCommerce and Cloudinary into Uniform and configuring the Uniform project
Uniform supports the integration of several third-party services, including BigCommerce and Cloudinary, for the creation of captivating digital experiences. So, integrate the product data on BigCommerce and the video on Cloudinary into Uniform, as follows:
- Log in to your Uniform account, click Create New Project at the top and name the project
uniform-shoppableClick to copy
. Click Continue. - Add the product to the Uniform project: Click the Products tab and then the product. Click the Integrations tab at the top.
- Next, click BigCommerce under Browse Integrations and then the Add to project button. Input the store hash and API token you added to the
.envClick to copy
file earlier in the appropriate text fields. Click Save. - Follow the same steps to add the Cloudinary integration: Input your Cloudinary account’s
cloudnameClick to copy
and API key and then click Save.The values of yourcloudnameClick to copy
and API key are displayed in your Cloudinary account’s dashboard.
Finally, create a Uniform API key:
- Click the Security tab and then the + icon. Type
uniform-shoppableClick to copy
as the API name, click Add to Project, select all the permissions, and click Set Permissions. Click Create API Key.Uniform then displays the API key under Key and the project ID under Projects. - Update the
.envClick to copy
file with those credentials:1 UNIFORM_API_KEY=your-api-key-here 2 UNIFORM_PROJECT_ID=your-project-id-here
Creating the Uniform Components
A Uniform composition is a group of reusable building blocks that carry properties, just as React components do.
For this tutorial, create four components:
- Page, on which to mount other components.
- ShoppableVideo, in which to hold the Cloudinary video.
- Chapter, the chapter you’ll define for the Cloudinary Video Player.
- Hotspot, the hotspot you’ll define for the Cloudinary Video Player.
Do the following:
- Click the Canvas tab, followed by Component Library and the + icon, and then name the components appropriately.Since Page is a composition component, select the Composition Component setting.
- Define the slots: Click a component and then the Slots tab and the + icon. Select the appropriate component for each slot:
- The ShoppableVideo component is a slot of the Page component.
- The Chapter component is a slot of the ShoppableVideo component.
- The Hotspot component is a slot of the Chapter component.
- Define the parameters for the components: Click each of the components and then Parameters. Add the component properties as shown in the tables below the screenshot. Click OK.
ShoppableVideo
Parameter Name | Type |
---|---|
CTA | Text |
Cloudinary | Cloudinary |
Chapter
Parameter Name | Type |
---|---|
Chapter Title | Cloudinary |
Product | BigCommerce Product |
Start Time | Number |
End Time | Number |
Click Action | Dropdown List |
Hotspot
Parameter Name | Type |
---|---|
Time | Cloudinary |
X Position | Number |
Y Position | Number |
tooltipPosition | Dropdown List |
Creating the Uniform Compositions
Next, create the compositions for the components you created.
- In the Canvas tab, lick Compositions and then the + icon. Select Page as the component type, name the composition Shopping, and click Create.
- Type
/Click to copy
under Slug. - Specify the compositions for the ShoppableVideo, Chapter, and Hotspot components.
- Select Publish from the Save dropdown menu.
- Click the Canvas tab and then the Publish button to make your composition available to third-party applications.
Integrating Uniform with Next.js
Now integrate Uniform into your Next.js application.
Creating the VideoPlayer Component
To enable the
VideoPlayercomponentClick to copy
to hold the Cloudinary Video Player, create a components/VideoPlayer.jsClick to copy
file with the code below.1import "cloudinary-video-player/dist/cld-video-player.min.js";
2import "cloudinary-video-player/dist/cld-video-player.min.css";
3import { useEffect } from "react";
1export default function VideoPlayer = ({ cloudname, cta, video, products }) => {
2 useEffect(() => {
3 const videoPlayer = cloudinary.videoPlayer("shoppable-video-player", {
4 cloud_name: cloudname,
5 muted: true,
6 controls: true,
7 fluid: true,
8 });
9 var source = {
10 shoppable: {
11 startState: "openOnPlay",
12 bannerMsg: cta,
13 showPostPlayOverlay: true,
14 products,
15 },
16 };
17 if (products.length > 0) {
18 videoPlayer.source(video, source);
19 } else {
20 videoPlayer.source(video);
21 }
22 }, [video, products, cloudname, cta]);
23 return (
24 <div>
25 <video
26 id="shoppable-video-player"
27 className="cld-video-player cld-video-player-skin-light"
28 />
29 </div>
30 );
31};
The above code performs two tasks:
- Import the required dependencies.
- Configure the Cloudinary Video Player and ensure that the products exist before adding the source for the shoppable feature.
Creating the Resolve renderer
The resolver maps through the Uniform data and passes it to
ShoppableVideoClick to copy
. To make that happen, set up resolveRendererClick to copy
, which you passed to the CompositionClick to copy
component, by creating a components/ResolveRenderer.jsClick to copy
file with the code below.1import { DefaultNotImplementedComponent } from "@uniformdev/canvas-react";
2import ShoppableVideo from "./ShoppableVideo";
3const mappings = {
4 shoppablevideo: ShoppableVideo,
5};
6export function resolveRenderer(component) {
7 const componentImpl = mappings[component.type];
8 return componentImpl ? componentImpl : DefaultNotImplementedComponent;
9}
10export default mappings;
The above code performs two tasks:
- Import the required dependencies.
- Map through the
shoppableVideoClick to copy
data from Uniform and pass it to theShoppableVideoClick to copy
component.
Creating the ShoppableVideo component
Next, define the data that enables the functions of Cloudinary’s shoppable video. Create a
components/ShoppableVideo.jsClick to copy
file with the code below.
1import dynamic from "next/dynamic";
2import format from "format-duration";
1export default function ShoppableVideo({ component }) {
2 const DynamicVideo = dynamic(() => import("./VideoPlayer"), {
3 ssr: false,
4 });
5 const cta = component.parameters.cta.value;
6 const { publicId } = component.parameters.cloudinary.value[0];
7 const cloudname = your-cloud-name;
8 let products = [];
9
10 if (component.slots?.chapters) {
11 products = component.slots.chapters.map((chapter) => {
12 const { id, name, price, image } = chapter.parameters.product.value;
13 const clickAction = { args: {} };
14 if (chapter.parameters.clickAction.value === "goToProduct") {
15 clickAction.action = "goto";
16 clickAction.pause = true;
17 clickAction.args.url = `https://uniform-shoppable.mybigcommerce.com/${name}`;
18 } else {
19 clickAction.action = "seek";
20 clickAction.pause = true;
21 clickAction.args.time = format(
22 1000 * chapter.parameters.startTime.value,
23 { leading: true }
24 );
25 }
26 const hotspots = [];
27 if (chapter?.slots?.hotspots) {
28 const { time, tooltipposition, x, y } =
29 chapter.slots.hotspots[0].parameters;
30 hotspots.push({
31 time: format(1000 * time.value, { leading: true }),
32 x: `${x.value}%`,
33 y: `${y.value}%`,
34 tooltipPosition: tooltipposition.value,
35 clickUrl: `https://uniform-shoppable.mybigcommerce.com/${name}`,
36 });
37 }
38 const result = {
39 productId: id,
40 productName: `${name} - $${price}`,
41 startTime: Number(chapter.parameters.startTime.value),
42 endTime: Number(chapter.parameters.endTime.value),
43 publicId: image,
44 onClick: clickAction,
45 };
46 if (hotspots.length > 0) {
47 result.hotspots = hotspots;
48 }
49 return result;
50 });
51 }
52 const options = { video: publicId, cta, cloudname, products };
53 return (
54 <>
55 <DynamicVideo {...options} />
56 </>
57 );
58}
The above code does the following:
- Import the required documents.
- Dynamically import the
VideoPlayerClick to copy
component. - Retrieve the
ctaClick to copy
andpublicIdClick to copy
parameters from the component and define the value ofcloudnameClick to copy
, which you obtained from your Cloudinary account’s dashboard earlier. - Check whether the
chaptersClick to copy
slot exists inShoppableVideoClick to copy
and, if so, perform these tasks:- Map through the chapters and extract the values for
idClick to copy
,nameClick to copy
,priceClick to copy
, andimageClick to copy
. - Define the click action of the shoppable video’s products and execute the
gotoClick to copy
orseekClick to copy
action, depending on the value of theclickActionClick to copy
parameter. - Check whether the
hotspotsClick to copy
slot exists and, if so, configure the hotspots. Also verify that the length of thehotspotsClick to copy
array is greater than 0. - Configure and return a
resultClick to copy
object with information on each of the BigCommerce products.
- Set up an
optionsClick to copy
object to hold the configuration you’ll pass to Cloudinary to activate the shoppable-video feature.
Add an enhancer
Since Uniform stores only the reference ID and not the data you input while creating compositions, adding an enhancer helps you make queries, pull data, and transform the data into a structured format for the frontend.
Create an
enhancers/index.jsClick to copy
file with the code below.
1import { compose, EnhancerBuilder } from "@uniformdev/canvas";
2import {
3 CLOUDINARY_PARAMETER_TYPES,
4 cloudinaryEnhancer,
5} from "@uniformdev/canvas-cloudinary";
6import {
7 createBigCommerceClient,
8 createBigCommerceEnhancer,
9 CANVAS_BIGCOMMERCE_PARAMETER_TYPES,
10} from "@uniformdev/canvas-bigcommerce";
1export const bigCommerceClient = createBigCommerceClient({
2 storeHash: process.env.BIGCOMMERCE_STORE_HASH,
3 token: process.env.BIGCOMMERCE_API_TOKEN,
4});
1export const bigCommerceEnhancer = () =>
2 createBigCommerceEnhancer({
3 client: bigCommerceClient,
4 createProductOptions: () => {
5 return {
6 include_fields: ["id", "name", "price"],
7 };
8 },
9 });
10
11export const bigCommerceModelCleaner = ({ parameter }) => {
12 const { id, name, images, price } = parameter.value;
13 parameter.value = {
14 id,
15 name,
16 price,
17 image: images[0].url_standard,
18 };
19 return parameter.value;
20};
1export const enhancers = new EnhancerBuilder()
2 .parameterType(CLOUDINARY_PARAMETER_TYPES, cloudinaryEnhancer)
3 .parameterType(
4 CANVAS_BIGCOMMERCE_PARAMETER_TYPES,
5 compose(bigCommerceEnhancer(), bigCommerceModelCleaner)
6 );
The above code does the following:
- Import the required dependencies.
- Create
BigCommerceClientClick to copy
with the store hash and API key you saved earlier. - Created
BigCommerceEnhancerClick to copy
with thecreateBigCommerceEnhancerClick to copy
method and then define the product fields (idClick to copy
,nameClick to copy
, andpriceClick to copy
) with thecreateProductOptionsClick to copy
function. - Set up the
bigCommerceModelCleanerClick to copy
function, which extracts the data from the products and returns them. - Create a new instance of
EnhancerBuilderClick to copy
and pass to it the relevant parameters.
Getting composable data from Uniform
Update the
pages/index.jsClick to copy
file with the code below:
1import Head from "next/head";
2import { CanvasClient, enhance } from "@uniformdev/canvas";
3import { Composition, Slot } from "@uniformdev/canvas-react";
4import { enhancers } from "../enhancers";
5import { resolveRenderer } from "../components/ResolveRenderer";
1export default function IndexPage({ composition }) {
2 return (
3 <div>
4 <Head>
5 <title>Shoppable Video with Cloudinary, Uniform and BigCommerce</title>
6 </Head>
7 <Composition data={composition} resolveRenderer={resolveRenderer}>
8 <Slot name="components" />
9 </Composition>
10 </div>
11 );
12}
1export async function getStaticProps() {
2 const client = new CanvasClient({
3 apiKey: process.env.UNIFORM_API_KEY,
4 projectId: process.env.UNIFORM_PROJECT_ID,
5 });
6 const { composition } = await client.getCompositionBySlug({
7 slug: "/",
8 });
9 await enhance({
10 composition,
11 enhancers,
12 context: {},
13 });
14 return {
15 props: {
16 composition,
17 },
18 };
The above code does the following:
- Import the required dependencies.
- Fetch data from Uniform with the
getStaticPropsClick to copy
function, which also performs these three tasks:- Create a
CanvasClientClick to copy
instance with the API key and project ID. - Fetch
compositionClick to copy
through thegetCompositionBySlugClick to copy
method in theCanvasClientClick to copy
instance. - Render the data you fetched from Uniform with the
CompositionClick to copy
andSlotClick to copy
components.
You’ve now created a shoppable video with Cloudinary, BigCommerce, and Uniform. Of significance is Uniform’s support of third-party integrations, which facilitates the creation of engaging digital experiences through a combination of Uniform and best-in-class technologies.