Events
The widget exposes an event-driven API. Attach listeners in your application and keep business logic there.
The widget exposes an event-driven API. Attach listeners in your application and keep business logic there.
Required handlers
For commerce integrations, these two handlers are required:
add_to_cartsend_to_checkout
Without both handlers, users may see widget suggestions they cannot complete in your storefront flow.
Register and remove listeners
const onAddToCart = (data: { products: Array<{ productId: string; variantId?: string }> }) => {
console.log("add_to_cart", data.products);
};
widget.on("add_to_cart", onAddToCart);
// Later, cleanup:
widget.off("add_to_cart", onAddToCart);Event reference
ready
Fired when the widget is ready to use.
widget.on("ready", () => {
console.log("Widget ready");
});add_to_cart
Fired when the widget requests adding products to cart.
Host app responsibility:
- resolve variant if needed
- call your cart API/action
- after cart is updated, call
widget.updateUserCart(...)so widget state stays aligned
Payload shape:
type AddToCartEvent = {
products: Array<{
productId: string;
variantId?: string;
}>;
};Example:
widget.on("add_to_cart", async (data) => {
for (const product of data.products) {
// Resolve variant if needed, then call your cart API/action
await addToCartInYourApp(product);
}
widget.updateUserCart({
cartId: cartId,
items: latestCartItems,
});
});add_to_favorite
Fired when the user toggles favorites on a product and the SDK has validated the payload and resolved an identifier.
Subscription. Register a listener with widget.on("add_to_favorite", (data: AddToFavoriteEvent) => { ... }). The literal "add_to_favorite" is also available as IncomingMessageTypes.ADD_TO_FAVORITE from the package if you prefer a constant.
Types. AddToFavoriteEvent and AddToFavoritePayload are the same shape; import either from @usesophi/sophi-web-sdk, along with Product, ProductSummary, and optionally IncomingMessageTypes.
Payload. The callback receives:
product(Product | ProductSummary): Full product context for your UI or integrations.isFavorite(boolean): Whether the product is favorited after the user’s action (the resulting state).productIdentifier(string): Convenience id string computed by the SDK fromproductso you do not need your own fallback logic.
productIdentifier resolution. The SDK derives the value in this order: use a non-empty externalId on product if present; else String(product.id) if id is present; else a non-empty productId on product if present. If none of these apply, the SDK does not emit add_to_favorite.
Invalid or missing data. If validation fails or productIdentifier cannot be derived, the SDK does not fire add_to_favorite (it may log a console warning). You do not need to handle malformed payloads for this event.
Example:
import { type AddToFavoriteEvent, IncomingMessageTypes } from "@usesophi/sophi-web-sdk";
widget.on("add_to_favorite", (data: AddToFavoriteEvent) => {
syncWishlist(data.productIdentifier, data.isFavorite, data.product);
});
// Equivalent:
widget.on(IncomingMessageTypes.ADD_TO_FAVORITE, (data: AddToFavoriteEvent) => {
syncWishlist(data.productIdentifier, data.isFavorite, data.product);
});send_to_checkout
Fired when user should be redirected to checkout.
Host app responsibility:
- navigate user to your checkout route immediately
- optionally close/hide any custom modal around the widget
widget.on("send_to_checkout", () => {
window.location.href = "/checkout";
});error
Fired when the widget reports an error.
widget.on("error", (error: Error) => {
console.error("Sophi error", error.message);
});Initialization
Initialize the widget in your application after the SDK is loaded and the target container is available in the DOM.
Methods
Reference for the SophiWidget instance methods — lifecycle (init, destroy, isReady), visibility, cart updates, sending messages and product replies, and event subscription.