How to show variant color swatches using metafields
This guide will help you to show variant color swatches using metafields.
Let's divide this guide into two parts:
- How to configure variant metafields in Shopify.
- How to show variant color swatches in the app.
How to configure variant metafields in Shopify
- Go to your Shopify admin panel.
- Click on settings.
- Click on Custom Data.
- Select Variants
- Click on Add definition.
Give the name,namespace and key.
Select the type as file.
Select images as file type.
Enable storefronts on access section.
Click on Save.
Go to Products → select a product → click on Edit on the variant.
- Go to Metafields at the bottom of the page and you can see the metafield you created.
Click on Select image and select the image you want to show as a color swatch.
Click on Save.
How to show variant color swatches in the app
Add the following code in the
activate
function of theindex.js
file of theshopify
package.import { addMetaFields } from './helper';
export function activate(params) {
addMetaFields();
}You can get the extra metafields of the variant by using the
addMetafieldsToVariant
function of themetafieldsHelper
.For example, you can create a helper file
helper.js
in the your theme and add the following code.import { metafieldsHelper } from '@appmaker-xyz/shopify';
export function addMetaFields() {
metafieldsHelper.addMetafieldsToVariant({
namespace: 'custom',
key: 'variant_color',
});
}Replace the variation block of product detail page.
Variations block is used to show the product options in the product detail page. You can replace the variation block by adding the following code in the
blocks/index.js
file of the theme.import ShopifyProductOptions from '../components/product-variation-chooser';
const blocks = [
{
name: 'appmaker/shopify-product-variation', // default variation block name
View: ShopifyProductOptions, // replace the default variation block with the ShopifyProductOptions component
},
];
export { blocks };Write the component -
components/prduct-variation-chooser.js
. You can use the hookuseProductOptions
to get the product variation details. The metafield value of the variant is available in thevariants
object of theuseProductOptions
hook.You can use the
getMediaImage
function to get the image url of the metafield since you get the metafield value as a file id.Below is the sample code of the
components/prduct-variation-chooser.js
file. You can customize the code as per your requirement.import React, { useState, useEffect } from 'react';
import { Pressable, StyleSheet, Text, View, ScrollView, Image } from 'react-native';
import { useProductOptions } from '@appmaker-xyz/shopify';
import { getMediaImage } from '../getmediaimage';
const ProductVariationChooser = (props) => {
const {
variationOptions,
setOption,
selectedOptions,
variants
} = useProductOptions(props);
const [variantImages, setVariantImages] = useState({});
useEffect(() => {
async function fetchImages() {
const images = {};
for (const variant of variants.edges) {
const customVariantColor = variant.node.custom_variant_color?.value;
if (customVariantColor) {
const response = await getMediaImage(customVariantColor);
const imageUrl = response?.data?.data?.nodes[0]?.image?.url;
images[variant.node.title] = imageUrl;
}
}
setVariantImages(images);
}
fetchImages();
}, [variants]);
return (
<>
{variationOptions.map((options) => {
return (
<ScrollView
contentContainerStyle={styles.TextContainer}
horizontal
showsHorizontalScrollIndicator={false}
key={options.key}
>
{options?.options?.map((item) => {
const selectedOption = selectedOptions && selectedOptions[options?.key];
const isSelected = selectedOption === item.value;
// Find the variant based on the selected option
const variant = variants.edges.find((edge) =>
edge.node.selectedOptions.some(
(option) =>
option.name === options.key && option.value === item.value
)
);
// Extract the custom_variant_color value from the corresponding variant
const customVariantColor =
variant && variant.node.custom_variant_color?.value;
const customVariantImageUrl = variantImages[variant.node.title];
return (
<Pressable
key={item.value}
onPress={() => setOption(options.key, item.value)}
>
<View style={styles.variantItem}>
{customVariantImageUrl && (
<Image
source={{ uri: customVariantImageUrl }}
style={styles.variantImage}
/>
)}
<Text
style={
isSelected ? styles.selectedText : styles.titleText
}
>
{item.label}
</Text>
</View>
</Pressable>
);
})}
</ScrollView>
);
})}
</>
);
};
const styles = StyleSheet.create({
TextContainer: {
fontFamily: 'Urbanist-Regular',
},
variantItem: {
flexDirection: 'row',
alignItems: 'center',
marginRight: 16, // Add spacing between variants
},
variantImage: {
width: 50,
height: 50,
marginRight: 8, // Add spacing between image and variant label
},
titleText: {
color: 'black',
borderWidth: 0.5,
alignSelf: 'flex-start',
paddingVertical: 14,
paddingHorizontal: 22,
textTransform: 'uppercase',
letterSpacing: 4,
fontSize: 16,
fontFamily: 'Urbanist-Regular',
},
selectedText: {
color: 'black',
borderWidth: 0.5,
alignSelf: 'flex-start',
paddingVertical: 14,
paddingHorizontal: 22,
textTransform: 'uppercase',
letterSpacing: 4,
backgroundColor: '#F3FBFF',
fontSize: 16,
overflow: 'visible',
fontFamily: 'Urbanist-Bold',
},
});
export default ProductVariationChooser;Write the
getMediaImage
function in thegetmediaimage.js
file.
import { runDataSource } from "@appmaker-xyz/core";
export const getMediaImage = async(data)=>{
const dataSource = {
attributes: {},
source: "shopify",
};
const [response] = await runDataSource(
{
dataSource,
},
{
methodName: "gqlQuery",
params: {
query: `
query getMediaImages($ids: [ID!]!) {
nodes(ids: $ids) {
... on MediaImage {
alt
id
image {
url(transform:{maxHeight: 800, maxWidth: 800})
}
}
}
}
`,
variables: {
"ids": data
}
},
}
);
//console.log('response = ', response)
return response;
}
Result: