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 render
  • message — banner text, with dynamic variables
  • icon — 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 render
  • blocks[] — 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 campaign
    • message — 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 UI
  • isUnlocked — whether the customer has met eligibility requirements
  • buttonsDisabled — whether claim buttons should be disabled
  • promoBarTitle — text displayed in the collapsible header
  • promoBarIcon — icon displayed in the collapsible header
  • bannerMessage — message displayed above the gift list
  • bannerIcon — icon displayed with the banner message
  • gifts[] — available gifts with price, variants, and selection state
  • showPromoBar — whether to display the promo bar header
  • showCollapsible — 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

  • cartTotal and progressPercentage — live cart state
  • allTiers — array of tiers with thresholds and unlocked state
  • settings — 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 tiers
  • variantPickerOptions — available options for variant selection
  • header — 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 with eligibility (e.g., "Buy 2") and discount (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 config atom describing its current UI state.
  • Subscribe with .subscribe(cb) or .get() in plain JS.
  • Use useStore() in React or StoreController in Lit.
  • Shapes differ per controller (ProductBannerConfig, GWPConfig, TieredCartProgressUIState, VolumeDiscountConfig).