Hype UI SDK Reference
Learn how to subscribe to Hype UI SDK controller state using Nanostores or plain JavaScript. Includes config types for Product Banner, GWP, Tiered Cart, and Volume Discounts.
Overview
Each Hype UI SDK controller exposes a Nanostores atom called config.
This atom holds the current UI state for the block (banner, tiered cart, gift with purchase, volume discount).
You can read its value directly, subscribe to changes, or integrate it with React, Preact, or Lit using official Nanostores adapters.
ProductBannerController
Config type
type ProductBannerConfig = {
isVisible: boolean;
message: string; // supports {{discount}} and {{discount_code}}
icon: Icon;
};
Usage
isVisible— whether the banner should rendermessage— banner text, with dynamic variablesicon— emoji or SVG name
ProductPriceController
Config type
type ProductPriceBlock =
| {
type: 'original_price';
isStrikedOff: boolean;
text: string;
}
| {
type: 'discounted_price';
text: string;
}
| {
type: 'message';
isBadge: boolean;
text: string;
};
type ProductPriceConfig = {
isVisible: boolean;
blocks: ProductPriceBlock[];
};
Usage
isVisible— whether the price block should renderblocks[]— array of price blocks to display (up to 3)- Each block can be:
original_price— shows product's original price (optionally striked)discounted_price— shows discounted price after applying campaignmessage— custom message with variable support (optionally as badge)
Supported variables
The message block type supports these template variables:
{{discount_code}}— the campaign's discount code{{product_price}}— formatted original product price{{discounted_price}}— formatted price after discount{{discount_amount}}— formatted discount amount{{discount_percentage}}— discount as percentage (e.g., "20%")
GwpBannerController
Config type
type GwpConfig = {
showGifts: boolean;
isUnlocked: boolean;
buttonsDisabled: boolean;
isLoading: boolean;
promoBarTitle: string;
promoBarIcon: Icon;
bannerMessage: string;
bannerIcon: Icon;
gifts: Gift[];
showPromoBar: boolean;
showCollapsible: boolean;
};
Usage
showGifts— toggle visibility of the gift UIisUnlocked— whether the customer has met eligibility requirementsbuttonsDisabled— whether claim buttons should be disabledpromoBarTitle— text displayed in the collapsible headerpromoBarIcon— icon displayed in the collapsible headerbannerMessage— message displayed above the gift listbannerIcon— icon displayed with the banner messagegifts[]— available gifts with price, variants, and selection stateshowPromoBar— whether to display the promo bar headershowCollapsible— whether the banner should be collapsible
TieredCartController
Config type
type TieredCartProgressUIState = {
cartTotal: number;
progressPercentage: number;
nextTier?: {
index: number;
remainingAmount: number;
label: string;
isPrimaryMarketValue: boolean;
};
allTiers: TierUI[];
settings: TieredCartSettings;
message: string;
successMessages: string[];
isLoading: boolean;
};
type TierUI = {
index: number;
minAmount: number;
isPrimaryMarketValue: boolean;
isUnlocked: boolean;
label: string;
icon: Icon;
positionPercent: number;
successMessage: string;
showOffers: string;
isDisabled?: boolean;
gifts?: Gift[];
};
type TieredCartSettings = {
identifier: string;
useCustomCode: boolean;
showIcon: boolean;
title: string;
successMessage: string;
showOffers: string;
goals: Array<FreeGiftGoal | NonGiftGoal>;
header: {
icon: Icon;
text: string;
};
};
type FreeGiftGoal = {
text: string;
icon: Icon;
successMessage: string;
goalName: string;
type: 'freeGift';
giftBlock: {
showGiftBlock: boolean;
badge: {
icon: Icon;
text: string;
};
giftSubtitle: string;
description: string;
claimButtonText: string;
claimedButtonText: string;
};
};
type NonGiftGoal = {
text: string;
icon: Icon;
successMessage: string;
goalName: string;
type: 'freeShipping' | 'amountOff';
};
Usage
cartTotalandprogressPercentage— live cart stateallTiers— array of tiers with thresholds and unlocked statesettings— controller settings (custom code, titles, messages)showOffers— controls when offers/gifts are displayed (e.g., 'currentGoal', 'hideGoal')
VolumeDiscountController
Config type
type VolumeDiscountConfig = {
isVisible: boolean;
isLoading: boolean;
tiers: VolumeDiscountTier[];
header: VolumeDiscountHeader;
hasVariants: boolean;
variantPickerOptions: Record<string, string[]>;
};
type VolumeDiscountTier = {
cartEligibility: CartEligibility;
customerGets: CustomerGets;
popularBadge?: { icon: Icon; label: string };
title: string;
discountBadgeText: string;
selectedVariants: Record<string, SelectedVariant>;
strikeOriginalPrice: boolean;
showAmountOffOrPercentageBadges: boolean;
};
type SelectedVariant = {
variantId: number;
selectedOptions: Record<string, string>;
price: number;
available: boolean;
imageSrc: string | null;
};
type CartEligibility = {
type: 'quantity' | 'amount';
value: MarketWiseValueProxy;
};
type CustomerGets = {
appliesToEachItem: boolean;
type: 'percentage' | 'amount';
value: MarketWiseValueProxy;
};
type MarketWiseValueProxy = {
isPrimaryMarketValue: boolean;
value: number;
};
Usage
tiers[]— list of quantity/amount-based discount tiersvariantPickerOptions— available options for variant selectionheader— title and icon to render above discount table
VolumeDiscountTableController
Config type
type VolumeDiscountTableConfig = {
isVisible: boolean;
isLoading: boolean;
tiers: VolumeDiscountTier[];
header: VolumeDiscountHeader;
};
type VolumeDiscountTier = {
eligibility: string;
discount: string;
};
Usage
tiers[]— list of discount tiers, each witheligibility(e.g., "Buy 2") anddiscount(e.g., "Save 10%") details.header— title and icon to render above discount table
Subscribing to controllers
Vanilla JS
const ctrl = new window.HypeUI.TieredCartController('block-id');
ctrl.config.subscribe((cfg) => {
console.log('Cart progress:', cfg.progressPercentage);
});
React
import { useStore } from '@nanostores/react';
function TieredCart({ identifier }) {
const ctrl = React.useMemo(
() => new window.HypeUI.TieredCartController(identifier),
[identifier]
);
const cfg = useStore(ctrl.config);
return (
<div>
{cfg.message} ({cfg.progressPercentage}%)
</div>
);
}
Common Types
The following types are used across the different controller configurations.
// Common icon type used in multiple controllers
type Icon = {
type: 'filled' | 'outlined' | 'emoji' | 'none';
name: string;
};
Only the icons listed below can be used when the type is ‘filled’ or ‘outlined’. If the type is ‘emoji’, you may use any valid Unicode emoji supported by the store’s theme. For the ‘none’ type, leave the name field empty.
Filled Icons
| # | Icon Name | # | Icon Name | # | Icon Name | ||
|---|---|---|---|---|---|---|---|
| 1 | MegaPhone1Filled | 11 | Dollar1Filled | 21 | Timer3Filled | ||
| 2 | MegaPhone2Filled | 12 | Dollar2Filled | 22 | Timer4Filled | ||
| 3 | Heart1Filled | 13 | Dollar3Filled | 23 | Percentage1Filled | ||
| 4 | Heart2Filled | 14 | Dollar4Filled | 24 | Percentage2Filled | ||
| 5 | Confetti1Filled | 15 | Diamond1Filled | 25 | Percentage3Filled | ||
| 6 | Confetti2Filled | 16 | Diamond2Filled | 26 | Percentage4Filled | ||
| 7 | Globe1Filled | 17 | Bell1Filled | 27 | ThumbsUp1Filled | ||
| 8 | Globe2Filled | 18 | Bell2Filled | 28 | ThumbsUp2Filled | ||
| 9 | HandShake1Filled | 19 | Timer1Filled | 29 | Shipping1Filled | ||
| 10 | HandShake2Filled | 20 | Timer2Filled | 30 | Check1Filled |
Outlined Icons
| # | Icon Name | # | Icon Name | # | Icon Name | ||
|---|---|---|---|---|---|---|---|
| 1 | MegaPhone1Outlined | 12 | Dollar2Outlined | 23 | Percentage1Outlined | ||
| 2 | MegaPhone2Outlined | 13 | Dollar3Outlined | 24 | Percentage2Outlined | ||
| 3 | Heart1Outlined | 14 | Dollar4Outlined | 25 | Percentage3Outlined | ||
| 4 | Heart2Outlined | 15 | Diamond1Outlined | 26 | Percentage4Outlined | ||
| 5 | Confetti1Outlined | 16 | Diamond2Outlined | 27 | ThumbsUp1Outlined | ||
| 6 | Confetti2Outlined | 17 | Bell1Outlined | 28 | ThumbsUp2Outlined | ||
| 7 | Globe1Outlined | 18 | Bell2Outlined | 29 | Shipping1Outlined | ||
| 8 | Globe2Outlined | 19 | Timer1Outlined | 30 | Check1Outlined | ||
| 9 | HandShake1Outlined | 20 | Timer2Outlined | 31 | Check2Outlined | ||
| 10 | HandShake2Outlined | 21 | Timer3Outlined | ||||
| 11 | Dollar1Outlined | 22 | Timer4Outlined |
// GWP & Tiered Cart types
type Gift = {
title: string;
price: number;
images: string[];
giftSubtitle: string;
description: string;
isAddedToCart: boolean;
buttonText: string;
variants: ProductVariant[];
options: ProductOption[];
featuredImage: string;
badge: { icon: Icon; text: string };
};
interface ProductVariant {
id: number;
title: string;
options: string[];
price: number;
available: boolean;
}
interface ProductOption {
name: string;
position: number;
values: string[];
}
// Volume Discount types
type VolumeDiscountHeader = {
icon: Icon;
title: string;
};
Key takeaways
- Each controller has a
configatom describing its current UI state. - Subscribe with
.subscribe(cb)or.get()in plain JS. - Use
useStore()in React orStoreControllerin Lit. - Shapes differ per controller (
ProductBannerConfig,GWPConfig,TieredCartProgressUIState,VolumeDiscountConfig).