Skip to main content

Discount Percentage and Sold Out Sticker

A Product Sticker that shows the discount as a percentage (e.g. "-25%") when a product is on sale, a "Sold out" badge when it's unavailable, and nothing otherwise.

Example​

import React from 'react';
import { Box, Text } from '@evlop/native-components';
import { CustomBlock } from '@evlop/shopify';

const DiscountSticker: CustomBlock.ProductSticker = ({ data }) => {
const { product } = data;
if (!product || product.isLoading) return null;

const variant = data.variant ?? product.variants?.[0];
if (!variant) return null;

if (variant.availableForSale === false) {
return (
<Box bg="gray-800" px={8} py={4} borderRadius={4} style={{ position: 'absolute', top: 8, left: 8 }}>
<Text fontSize="xs" fontWeight="Bold" color="gray-0">Sold out</Text>
</Box>
);
}

const price = +(variant.price?.amount ?? 0);
const compareAtPrice = +(variant.compareAtPrice?.amount ?? 0);
if (!compareAtPrice || compareAtPrice <= price) return null;

const discountPercentage = Math.round((1 - price / compareAtPrice) * 100);
if (discountPercentage < 1) return null;

return (
<Box bg="red-600" px={8} py={4} borderRadius={4} style={{ position: 'absolute', top: 8, left: 8 }}>
<Text fontSize="xs" fontWeight="Bold" color="gray-0">-{discountPercentage}%</Text>
</Box>
);
};

export default DiscountSticker;

How it works​

  • Use the variant when there is one. data.variant is the specific variant the sticker is shown for; when it's missing, the product's first variant is used instead.
  • Sold out takes priority. variant.availableForSale === false shows the "Sold out" badge instead of a discount, since a discount on an item that can't be bought isn't useful.
  • The discount is computed from the prices. price and compareAtPrice are { amount, currencyCode } objects with the amount as a string, so they're converted to numbers with + first. A product is only on sale when it has a compare-at price higher than its price.
  • Return null to show nothing. For products that aren't on sale or sold out - and while the product is still loading - the sticker renders nothing at all.
  • Keep it compact and in a corner, as described on the Product Sticker page.