Message Events

The Stylux SDK emits general messages via a pubsub pattern. These are similar to events in how they're processed/consumed, but rather than a regular or custom event, you can subscribe to topics using the Stylux.pubsub.subscribe method.

For example:

Stylux.pubsub.subscribe('CLOSE_MODAL', (e) => {
  // handle message/event here
});

Message Topics

Message TopicMessage Data
SETUP_COMPLETEundefined
SHOW_OFFERundefined
HIDE_OFFERundefined
OPEN_MODALIModalState
CLOSE_MODALIModalClosingState
BUNDLE_CREATEIBundleCreateData

Where each of the above interfaces are defined as:

interface IModalState {
  openingSource: 'ADD_TO_CART' | 'STYLUX_OFFER';
  offer: IOffer;
  product: IProduct;
}

interface IModalClosingState {
  openingSource: 'ADD_TO_CART' | 'STYLUX_OFFER';
  closingSource: 'NO_THANKS' | 'CLOSE_BUTTON' | 'BACKDROP' | 'UNKNOWN';
  offer: IOffer;
  product: IProduct;
}

interface IBundleCreateData {
  product: IProduct;
  offer: IOffer;
  bundle: IBundleApiResponse;
}

Handling Bundle Creation

The BUNDLE_CREATE event is important to handle, as this is the event emitted when a bundle is created from the Stylux modal. When this occurs we generally want to handle adding the appropriate products to the cart.

For example:

Stylux.pubsub.subscribe(
  'BUNDLE_CREATE',
  ({ product, offer, bundle, entries }) => {
    if (!bundle) {
      return;
    }

    const baseProductId = product.productId;
    const associatedProductsByType = new Map();

    offer?.associatedProducts?.nodes.forEach((associatedProduct) => {
      if (associatedProduct.product) {
        associatedProductsByType.set(
          associatedProduct.type,
          associatedProduct.product,
        );
      }
    });

    const textUpsellProductId =
      associatedProductsByType.get('TEXT_UPSELL')?.productId;

    const iconUpsellProductId =
      associatedProductsByType.get('ICON_UPSELL')?.productId;

    const hasTextEntriesWithPlacement = entries.some(
      (entry) => entry.simpleText?.placementId,
    );

    const hasIconEntriesWithPlacement = entries.some(
      (entry) => entry.icon?.placementId,
    );

    const products = [
      {
        productId: baseProductId,

        properties: {
          _STYLUX_BUNDLE: bundle.id,
        },
      },
    ];

    if (hasTextEntriesWithPlacement && textUpsellProductId) {
      products.push({
        productId: textUpsellProductId,

        properties: {
          _STYLUX_BUNDLE: bundle.id,
        },
      });
    }

    if (hasIconEntriesWithPlacement && iconUpsellProductId) {
      products.push({
        productId: iconUpsellProductId,

        properties: {
          _STYLUX_BUNDLE: bundle.id,
        },
      });
    }

    return addToCart({ products });
  },
);

Note: you'll have to replaceaddToCart with your actual APIs to handle adding products to cart with the appropriate hidden _STYLUX_BUNDLE line item property. If you're using standard out of the box Shopify/non-headless, this is handled automatically for you as part of the SDK's Shopify plugin.