Skip to main content

Building a Shoppable Videos mini

What will you learn?

In this guide, you'll learn how to do the following:

  • Create a mini from a template.
  • Set up an extension.
  • Accept data from an entry point.
  • Render a list of videos.

Prerequisites

This guide assumes that you have your test store set up and that you have already been onboarded to the Minis Platform.

Step 1: Use the Shoppable Videos template to create your mini

The CLI provides some templates for common use cases for a mini. That includes a template for mini that displays a feed of videos and products related to each video. We call this template "Shoppable Videos".

npm init @shopify/shop-mini@latest

Follow the prompts and choose the Shoppable Videos template when asked.

Step 2: Set up your mini's extension

When you created your mini, you would have been prompted to create an extension. If you chose to create an extension, you may proceed to the next step. If you didn't, you can run the shop-minis create-extension command to create one. We'll choose the Link extension at the Product Page - Before Variants Picker target for this example.

npx shop-minis create-extension

The Link extension comes with a basic query input.graphql that fetches the product's title. This data will be passed into the mini.

Step 3: Reading data from the extension

In your mini you can see the template code using the useMinisParams() hook to get an extensionData object which contains data that the extension has fetched.

const {extensionData} = useMinisParams<MyExtensionDataType>()

The useMinisParams hook above is assigned a stub type to gives typing to extensionData. We can replace it with the type generated from the extension's input query.

import {ProductVariantsRenderBeforeQueryData} from './targets/shop.product.variants.render-before/input.graphql'

// ...

const {extensionData} = useMinisParams<ProductVariantsRenderBeforeQueryData>()

Now we can access the shop's ID from the query.

Step 3: Fetch image URLs from a product metafield

Before we continue with this step, please follow the guide on metafields first. This step assumes that your products have a metafield with the key of videos and the type list.url.

Let's update our extension's query to fetch URLs of videos related to the product.

query ProductVariantsRenderBefore {
product {
id
title
videos: metafield(namespace: "app--12345--foo", key: "videos") {
value
}
}
}

Now lets start the mini dev server.

npm start

Navigate to the product screen to load your Link extension and press on it to open the mini. We'll see that the extensionData now contains a stringified array of image URLs from the metafield.

Step 4: Rendering a list of videos

In the template code we can see usage of a ShoppableVideos component. The component is using data from a fixture variable shoppableVideosFixture.

Now that we are able to query custom data from the product metafield, we can explore the shape of shoppableVideosFixture to see what data we have to provide to the component. We can add more metafields if needed.

Eventually, we should be able to replace shoppableVideosFixture with data from the query and / or other sources.

Step 5: Customizing your Shopable Videos mini

You can customize the look and feel of your Shoppable Videos mini by using the ShoppableVideos component's props. You can find the full list of props here: ShoppableVideosProps.

Example

// ...
<ShoppableVideos
items={shoppableVideos}
shopId={shopId}
fetchMore={fetchMore}
renderItem={({item}) => (
<View>
<CustomVideoHeader />
<Video
source={{uri: item.videoUrl}}
style={{height, width: 'auto'}}
poster={item.fallbackImageUrl}
posterResizeMode="cover"
repeat
resizeMode="cover"
paused={false}
progressUpdateInterval={10}
muted
ignoreSilentSwitch="ignore"
testID="video"
/>
<CustomVideoFooter />
</View>
)}
/>
// ...

Feed screen of a Shoppable Videos Mini with custom UI

// ...
<ShoppableVideos
items={shoppableVideos}
shopId={shopId}
fetchMore={fetchMore}
renderMedia={({item}) => <CustomCarouselPost images={imageStack(item)} />}
/>
// ...

Feed screen of a Shoppable Videos Mini with custom UI

// ...
<ShoppableVideos
items={shoppableVideos}
shopId={shopId}
fetchMore={fetchMore}
renderMediaHeader={() => null}
/>
// ...

Feed screen of a Shoppable Videos Mini with custom UI

// ...
<ShoppableVideos
items={shoppableVideos}
shopId={shopId}
fetchMore={fetchMore}
renderMediaFooter={({item}) => (
<View>
<Pressable
onPress={() => setShowGift(!showGift)}
style={{
justifyContent: 'flex-end',
marginBottom: 20,
}}
>
<IconButton
name="gift"
onPress={() => setShowGift(!showGift)}
accessibilityLabel="products"
/>
</Pressable>
<RelatedProductsList
products={item.relatedProducts}
style={RELATED_PRODUCTS_LIST_STYLE}
shopId={shopId}
/>
{showGift ? (
<GiftBottomSheet
text='Use PROMO2023 to get 10% off your purchase'
/>
) : null}
</View>
)}
/>
// ...

Feed screen of a Shoppable Videos Mini with custom UI


Feed screen of a Shoppable Videos Mini with custom UI

We look forward to seeing what you build!