Shoppable videos let you turn video content into interactive shopping experiences. Display product bars alongside your videos, highlight products at specific moments, and enable users to click through to purchase pages—all while maintaining engagement with your content.
Key features
- Product bar display: Show a customizable sidebar with product images, names, and details that sits alongside your video player
- Time-based highlighting: Automatically highlight products when they appear in your video content
- Interactive overlays: Add clickable hotspots directly on the video to pinpoint product locations in each frame
- Flexible interactions: Configure hover and click behaviors—navigate to product pages, switch images, seek to timestamps, or show custom overlays
- Post-play carousel: Keep viewers engaged after the video ends with a product carousel overlay
- Consistent branding: Apply ImageKit transformations to standardize product images across size, format, quality, and effects
Use case: Shoppable videos work best for fashion lookbooks, product demos, influencer content, and any video where viewers might want to purchase featured items.
Setting up shoppable videos
Configure shoppable functionality through the shoppable parameter when setting up video source. The parameter accepts an object with UI configuration and a products array defining what to display and when.
Shoppable options
Configure the shoppable video component's appearance and behavior:
| Parameter | Description |
|---|---|
products (required)object[] | Array of products to display in the products bar. See Product options below. |
startState'closed' | 'open' | 'openOnPlay' | Initial state of the product bar when the video loads. Default: 'openOnPlay' |
toggleIconUrlstring | URL of the icon used to toggle the product bar visibility |
widthnumber | Width of the product bar as a percentage of the player's total width. Default: 20 |
autoClosenumber | Number of seconds before the product bar automatically closes after no user interaction. Default: 2 |
transformationobject[] | ImageKit transformations to apply to all product images in the products bar. Use this to standardize size, format, quality, or add brand overlays and effects. See Image Transformations. |
showPostPlayOverlayboolean | Whether to display a product carousel overlay after the video ends. Default: false |
Product options
Define products in the products array. Each product object contains product information, when it appears in the video, interaction behavior, and optional video hotspots.
Tip: Use highlightTime to automatically draw attention to products when they're visible in your video. Combine with onHover for preview images and onClick for purchase navigation.
| Parameter | Description |
|---|---|
productId (required)number | Unique identifier for the product. |
productName (required)string | Name of the product. |
imageUrl (required)string | ImageKit-powered URL of the product image. |
highlightTime | Time range when the product appears in the video. {
// Start time in seconds
start: number;
// End time in seconds
end: number;
}
|
onClick | Behavior when clicking the product in the products bar. {
// Action to perform
action: 'overlay' | 'seek' | 'goto' | 'switch';
// Optional pause behavior
pause?: boolean | number;
// Action-specific arguments
args: {
time?: string; // For 'seek' action
url?: string; // For 'goto' or 'switch' action
message?: string; // For 'overlay' action
};
}
|
onHover | Behavior when hovering over the product in the products bar. Same structure as {
// Action to perform
action: 'overlay' | 'seek' | 'goto' | 'switch';
// Optional pause behavior
pause?: boolean | number;
// Action-specific arguments
args: {
time?: string; // For 'seek' action
url?: string; // For 'goto' or 'switch' action
message?: string; // For 'overlay' action
};
}
|
hotspots | Array of clickable hotspots on the video itself. The hotspot appears when a user clicks a product from the products bar and the video pauses at the defined time. {
// Time when the hotspot appears (e.g., "00:02")
time: string;
// X position (e.g., "50%")
x: string;
// Y position (e.g., "50%")
y: string;
// URL to navigate to when clicked
clickUrl: string;
// Optional tooltip position
tooltipPosition?: 'left' | 'right' | 'top' | 'bottom';
}
|
Example
import { videoPlayer } from '@imagekit/video-player';
import '@imagekit/video-player/styles.css';
const player = videoPlayer('my-video', {
imagekitId: 'YOUR_IMAGEKIT_ID'
});
player.src({
src: 'https://ik.imagekit.io/<your-imagekit-id>/video.mp4',
shoppable: {
products: [
{
productId: 1,
productName: 'Sunglasses',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product1.jpg',
highlightTime: { start: 0, end: 5 },
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/1' }
}
},
{
productId: 2,
productName: 'Green Dress',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product2.jpg',
highlightTime: { start: 2, end: 8 },
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/2' }
}
},
{
productId: 3,
productName: 'Brown Bag',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product3.jpg',
highlightTime: { start: 7, end: 11 },
onHover: {
action: 'switch',
args: {
url: 'https://ik.imagekit.io/<your-imagekit-id>/product3-alt.jpg'
}
},
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/3' }
}
}
],
startState: 'openOnPlay',
autoClose: 2,
width: 20,
transformation: [{ width: 200, height: 200 }]
}
});
import { IKVideoPlayer } from '@imagekit/video-player/react';
import '@imagekit/video-player/styles.css';
function App() {
const ikOptions = {
imagekitId: 'YOUR_IMAGEKIT_ID'
};
const source = {
src: 'https://ik.imagekit.io/<your-imagekit-id>/video.mp4',
shoppable: {
products: [
{
productId: 1,
productName: 'Sunglasses',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product1.jpg',
highlightTime: { start: 0, end: 5 },
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/1' }
}
},
{
productId: 2,
productName: 'Green Dress',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product2.jpg',
highlightTime: { start: 2, end: 8 },
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/2' }
}
},
{
productId: 3,
productName: 'Brown Bag',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product3.jpg',
highlightTime: { start: 7, end: 11 },
onHover: {
action: 'switch',
args: {
url: 'https://ik.imagekit.io/<your-imagekit-id>/product3-alt.jpg'
}
},
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/3' }
}
}
],
startState: 'openOnPlay',
autoClose: 2,
width: 20,
transformation: [{ width: 200, height: 200 }]
}
};
return (
<IKVideoPlayer
ikOptions={ikOptions}
source={source}
/>
);
}
<template>
<IKVideoPlayer
:ikOptions="ikOptions"
:source="source"
/>
</template>
<script setup>
import { IKVideoPlayer } from '@imagekit/video-player/vue';
import '@imagekit/video-player/styles.css';
const ikOptions = {
imagekitId: 'YOUR_IMAGEKIT_ID'
};
const source = {
src: 'https://ik.imagekit.io/<your-imagekit-id>/video.mp4',
shoppable: {
products: [
{
productId: 1,
productName: 'Sunglasses',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product1.jpg',
highlightTime: { start: 0, end: 5 },
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/1' }
}
},
{
productId: 2,
productName: 'Green Dress',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product2.jpg',
highlightTime: { start: 2, end: 8 },
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/2' }
}
},
{
productId: 3,
productName: 'Brown Bag',
imageUrl: 'https://ik.imagekit.io/<your-imagekit-id>/product3.jpg',
highlightTime: { start: 7, end: 11 },
onHover: {
action: 'switch',
args: {
url: 'https://ik.imagekit.io/<your-imagekit-id>/product3-alt.jpg'
}
},
onClick: {
action: 'goto',
pause: true,
args: { url: 'https://example.com/product/3' }
}
}
],
startState: 'openOnPlay',
autoClose: 2,
width: 20,
transformation: [{ width: 200, height: 200 }]
}
};
</script>
Best practices
- Time products strategically: Set
highlightTimeranges when products are clearly visible in the video. Overlapping times are fine—viewers can see multiple products simultaneously. - Use clear product images: Apply consistent transformations (like
{ width: 200, height: 200 }) to ensure all product images are the same size and properly formatted. - Combine hover and click: Use
onHoverwithaction: 'switch'to show alternate product views, andonClickwithaction: 'goto'to navigate to product pages. - Test interaction timing: Set appropriate
pausedurations. Pausing for 2-3 seconds on click gives users time to read product details before navigating away. - Enable post-play overlay: Set
showPostPlayOverlay: trueto display a product carousel after the video ends, giving viewers one more chance to explore products. - Add video hotspots: Use hotspots to highlight product locations directly on the video frame, making it easier for viewers to identify which item you're showcasing.
- Optimize for mobile: Keep product bar width reasonable (
width: 20-25) to ensure the video remains visible on smaller screens.
Related features
- Video player overview: Learn about basic video player setup and configuration
- Subtitles & chapters: Add text tracks and chapter markers to your videos
- Playlist & recommendations: Create playlists or show recommended videos
- Image transformations: Learn about transforming product images for consistent appearance