Inline Previews & Autoplay
Add inline 3D firework previews directly into your product cards and detail pages – no clicking required. Hover over a product to see it instantly, or embed a permanent inline preview, similar to an inline YouTube embed.
This guide covers two related SDK methods:
glow.setupAutoplayPreviews()– passive hover/scroll previews on a product grid or feed.glow.setupInlinePreview()– a single embedded preview, ideal for product detail pages (PDPs).
Something not working? Always check your browser's JavaScript console for informative error messages provided by GLOW.
Before You Start
- Confirm you have a valid retailer ID and product IDs from GLOW.
- Make sure the GLOW SDK is loaded and
glow.initialize()has been called on the page – see the Advanced Integration Guide for setup. The examples below assume both are in place.
Autoplay Previews
glow.setupAutoplayPreviews() wires up a grid of product cards so previews play automatically inline:
- On desktop: hover over a product to start its preview.
- On mobile: scroll a product into the center of the viewport to start its preview.
Only one preview plays at a time per controller, and a single iframe is efficiently reused under the hood for performance.
HTML
Tag each product card with the brand and product IDs, and identify the area you want the preview to cover:
<div class="product-card" data-glow-brand-id="sample" data-glow-product-id="demo-500g">
<a href="/products/demo-500g">
<div class="product-image">
<img class="product-thumbnail" src="/images/demo-500g.jpg" alt="Demo 500g">
</div>
<h3>Demo 500g</h3>
<p>$99.99</p>
</a>
</div>
JavaScript
glow.setupAutoplayPreviews({
productSelector: '.product-card',
previewAreaSelector: '.product-image',
thumbnailSelector: '.product-thumbnail',
clickBehavior: 'follow-link'
});
Hover the product on desktop, or scroll it into view on mobile, and the preview fades in over the product image. Clicking the preview navigates to the product link, just like clicking the card itself.
You can call setupAutoplayPreviews() multiple times on the same page – for example, once for a featured row and once for the main grid. Each call manages its own iframe and active preview independently.
Standalone Inline Preview
glow.setupInlinePreview() mounts a single, permanent preview into a container on the page. This is best for product detail pages, where you want the preview to behave like an embedded video player.
HTML
Pick a container element you want the preview to fill:
<div class="glow-pdp-preview"></div>
JavaScript
glow.setupInlinePreview({
container: '.glow-pdp-preview',
brandId: 'sample',
productId: 'demo-500g'
});
The preview fills the entire container and lazy-loads based on the browser's native heuristics – above-the-fold embeds load right away, below-the-fold embeds wait until the user scrolls near them.
API Reference
setupAutoplayPreviews()
const controller = glow.setupAutoplayPreviews({ /* options */ });
Options
| Option | Type | Default | Description |
|---|---|---|---|
productSelector | string | required | CSS selector matching each product container. |
previewAreaSelector | string | required | CSS selector (within each product) for the element the preview should cover – typically the product image. |
rootSelector | string | 'body' | Nearest scroll container holding products. Set this only when products live in a nested scroll container; the selector also scopes productSelector. |
thumbnailSelector | string | – | Selector for an <img> element to clone into the corner of the preview while it's active. Useful for preserving product identity once the original image is covered. |
clickBehavior | 'open-preview' | 'follow-link' | 'none' | function | 'open-preview' | What happens when the active preview is clicked. See Click Behavior below. |
linkSelector | string | first <a> in product | Only used with clickBehavior: 'follow-link'. Selector for the link to dispatch a synthetic click on. |
extractDataFromElement | function | – | Custom function to extract product data from each product container. See Custom Data Extraction below. |
watchElements | boolean | false | If true, GLOW automatically tracks new product elements added or removed from the DOM. Otherwise, call controller.refresh() manually after dynamic updates. |
borderRadius | string | '0' | A CSS border-radius value applied to the preview iframe (e.g. '12px' or '12px 12px 0 0'). |
zIndex | number | – | Override the preview's CSS stacking order. Omit for default browser stacking. |
preload | 'first-intent' | 'idle' | 'first-intent' | When to create the underlying viewer iframe. 'first-intent' waits for the first hover/scroll. 'idle' warms it up earlier via requestIdleCallback. |
mobileBreakpointPx | integer | 640 | Viewport width at or below which scroll activation is used instead of hover activation. Should match your grid's single-column breakpoint. |
respectReducedMotion | boolean | false | If true, autoplay is disabled when the user has prefers-reduced-motion enabled. |
triggers | object | { hover: true, scroll: true } | Selectively disable an activation mode. Hover only applies above mobileBreakpointPx on devices with (hover: hover). Scroll only applies at or below mobileBreakpointPx. |
timing | object | see below | Fine-tune activation timing. |
timing defaults
The defaults are tuned to feel responsive without being twitchy. Override only the keys you want to change – the rest will fall back to these values.
timing: {
hoverIntentDelayMs: 250, // delay before starting a hover preview
scrollDwellDelayMs: 500, // delay before starting a scroll-centered preview
initialMobileCheckDelayMs: 2000, // grace period before the first scroll check on mobile
pageLoadScrollIgnoreMs: 1000 // ignore scroll activation right after page load
}
Click Behavior
clickBehavior controls what happens when a user clicks an active preview. The preview overlay sits above the iframe, so click behavior is consistent regardless of what's playing inside.
'open-preview'(default) – opens the full-screen GLOW preview, the same as the standard 3D preview button.'follow-link'– dispatches a synthetic click on the product's link element, so your SPA router or normal anchor navigation handles it. Defaults to the first<a>inside the product container; override withlinkSelector.'none'– does nothing.- A function –
(productElement, event) => void. Run any custom logic you want.
Custom Data Extraction
By default, GLOW reads product IDs from each product container in this order:
-
data-glow-products– a JSON array, used for combos. For example:<div class="product-card"
data-glow-products='[{"brandId":"sample","productId":"0001","startTime":0},{"brandId":"sample","productId":"0002","startTime":0}]'> -
data-glow-brand-idanddata-glow-product-id– for a single product, same as the rest of the SDK.
If your HTML stores IDs somewhere else, supply your own extractor:
extractDataFromElement: (productElement) => ({
brandId: productElement.dataset.brand,
productId: productElement.dataset.sku
})
For combos, return { products: [{ brandId, productId, startTime? }, ...] } instead.
Returned Controller
| Method | Description |
|---|---|
controller.refresh() | Re-scans the DOM for new or removed product elements. Useful when watchElements: false and you've just rendered new products (e.g. after a "load more" button). |
controller.destroy() | Tears down the controller, removes the iframe, and detaches all listeners. |
controller.pause() | Pauses the active preview, if any. |
controller.play() | Resumes the active preview, if any. |
pause() and play() are queued until the iframe is ready, so it's safe to call them right after setup.
setupInlinePreview()
const controller = glow.setupInlinePreview({ /* options */ });
Options
| Option | Type | Default | Description |
|---|---|---|---|
container | HTMLElement | string | required | The element (or CSS selector matching exactly one element) the preview will fill. |
brandId | string | – | Brand ID of the product to play. Pair with productId. |
productId | string | – | Product ID of the product to play. Pair with brandId. |
products | array | – | For combos and assortments. An array of { brandId, productId, startTime? } objects. |
extractDataFromElement | function | – | Fallback extractor used when none of brandId/productId/products is provided. Same shape as the autoplay version. |
thumbnailSelector | string | – | Selector for an <img> element to clone into the corner of the preview. Mostly useful when the preview replaces an existing product image. |
clickBehavior | 'open-preview' | 'none' | 'open-preview' | Whether clicking the preview opens the full-screen GLOW viewer. Standalone previews don't support 'follow-link' or callbacks – the user is already on the product page. |
borderRadius | string | – | A CSS border-radius value applied to the iframe (e.g. '12px'). |
Provide product data via brandId/productId or products directly. extractDataFromElement is a fallback for when product data attributes already exist on the container.
Returned Controller
| Method | Description |
|---|---|
controller.destroy() | Removes the iframe and detaches all listeners. |
controller.pause() | Pauses the preview. |
controller.play() | Resumes the preview. |
pause() and play() are queued until the iframe is ready.
There is no refresh() because the preview is bound to a single container. If the underlying product changes (e.g. on an SPA route change), call controller.destroy() and re-initialize.