Shopping Assistant SDK
Chat

Chat

Overview

The Chat component is a core UI component of the Shopping Assistant SDK that renders the complete chat interface, including conversation messages, initial prompts, loading states, and message rendering. It provides a fully functional chat experience with support for user messages, AI responses, product displays, and customizable styling.

Usage

// importing component
import { Chat } from "@unbxd-ui/react-shopping-assistant-components";

Code Example

import { UnbxdShoppingAssistantWrapper } from "@unbxd-ui/react-shopping-assistant-hooks";
import { Chat } from "@unbxd-ui/react-shopping-assistant-components";
 
function ShoppingAssistantApp() {
  return (
    <UnbxdShoppingAssistantWrapper 
      siteKey="YOUR_SITE_KEY" 
      apiKey="YOUR_API_KEY"
      storeConversationId="LOCALSTORAGE"
    >
      <div className="chat-container">
        <Chat />
      </div>
    </UnbxdShoppingAssistantWrapper>
  );
}
⚠️
Note:

The Chat component must be used within the UnbxdShoppingAssistantWrapper to ensure that the component and the shopping assistant functionality work properly.

Props

InitialMessageComponent

optional
React Component
  • A custom component to display an initial welcome message when the chat loads.
  • This component appears above the chat messages and initial prompts.
  • Default Value: A welcome message component with shopping assistant greeting.

prompts

optional
Array
  • An array of suggested conversation starters that appear when the chat is empty.
  • These prompts help users get started with the conversation.
  • Default Value: ["What are the trending products?", "What is the best product for my needs?"].

LoadingComponent

optional
React Component
  • A custom component to display while the AI is processing and generating responses.
  • Shows during API calls and conversation loading states.
  • Default Value:
const LoadingComponent = () => {
	return <div className="loading-component">Awaiting response...</div>;
};

UserIcon

optional
React Component
  • A custom icon component to display next to user messages.
  • Helps distinguish user messages in the conversation.
  • Default Value:
const UserIcon = () => {
	return <>Me</>;
};

AIAssistantIcon

optional
React Component
  • A custom icon component to display next to AI assistant messages.
  • Helps distinguish AI responses in the conversation.
  • Default Value:
const AIAssistantIcon = () => {
	return <>AI</>;
};

UserMessageComponent

optional
React Component
  • A custom component for rendering user messages in the chat.
  • Receives message and UserIcon as props.
  • Default Value:
const UserMessage = ({ message, UserIcon }: UserMessageProps) => {
    return <div className="user-message-container">
        <div className="user-message-text">
            {message}
        </div>
        <div className="user-message-icon-wrapper">
            {UserIcon && <UserIcon />}
        </div>
    </div>;
};

AIMessageComponent

optional
React Component
  • A custom component for rendering AI assistant messages in the chat.
  • Receives response, AIAssistantIcon, and other props for products and filters.
  • Default Value: Built-in AIMessage component with product display support.
const AIMessage = ({ response, AIAssistantIcon, viewMore = false, viewMoreLimit = 5, ProductComponent, FiltersComponent = Filters }: AIMessageProps) => {
	const { message, products = [], filters = [] } = response;
 
	const handleFilterClick = (field: string, option: string) => {
		// console.log(field, option);
	};
 
	const renderFilters = () => {
		return filters.map((filter: { [key: string]: any }) => {
			const { field, options } = filter;
			return <FiltersComponent key={field} field={field} options={options} onFilterClick={handleFilterClick} viewMore={viewMore} viewMoreLimit={viewMoreLimit} />;
		});
	};
 
	return (
		<div className="ai-message-container">
			<div className="ai-message-icon-wrapper">
				{AIAssistantIcon && <AIAssistantIcon />}
			</div>
			<div className="ai-message-wrapper">
				{message && <div className="ai-message-text">{message}</div>}
				{filters.length > 0 && renderFilters()}
				{products.length > 0 && <ProductCarousel label="Recommended Products:" products={products} ProductComponent={ProductComponent} />}
			</div>
		</div>
	);
};

viewMore

optional
boolean
  • Enables "View More" functionality for product listings in AI responses.
  • When enabled, limits initial product display and shows a button to reveal more products.
  • Default Value: false.

viewMoreLimit

optional
number
  • Sets the number of products to show initially before the "View More" button.
  • Only applies when viewMore is enabled.
  • Default Value: 5.
<Chat 
  viewMore={true} 
  viewMoreLimit={3} 
/>

ProductComponent

optional
React Component
  • A custom component for rendering individual products in AI responses.
  • Receives product data and handles product display and interactions.
  • Default Value:
const ProductComponent = ({ product }: ProductProps) => {
	const { imageUrl, title, price, uniqueId } = product;
 
	const handleProductClick = () => {
		// console.log(product);
	};
 
	return (
		<div data-idx={uniqueId} data-prank={uniqueId} className="product-container" onClick={handleProductClick}>
			<div className="product-image-container">
				<img src={imageUrl} alt={title} />
			</div>
			<div className="product-details-container">
				<div className="product-name">{title}</div>
				<div className="product-price">${price}</div>
			</div>
		</div>
	);
};

FiltersComponent

optional
React Component
  • A custom component for rendering filter options in AI responses.
  • Handles filter display and user interaction with search filters.
  • Default Value:
const Filters = ({ field, options, onFilterClick, viewMore = false, viewMoreLimit = 5 }: FiltersProps) => {
    const { askAgent } = useShoppingAssistant();
 
    const [filtersShown, setFiltersShown] = useState(options.slice(0, viewMore ? viewMoreLimit : options.length));
 
    const handleFilterClick = (option: string) => {
        askAgent(option, { field, options: [option] });
        onFilterClick && onFilterClick(field, option);
    };
 
    const handleViewClick = () => {
        setFiltersShown(filtersShown.length === options.length ? options.slice(0, viewMoreLimit) : options);
    }
 
    const renderFilters = () => {
        return filtersShown.map((option: string) => (
            <div
                className={`filter-option`}
                key={option}
                onClick={() => handleFilterClick(option)}
            >
                {option}
            </div>
        ));
    }
 
    const renderViewText = () => {
        const viewText = filtersShown.length === options.length ? "View Less" : "View More";
 
        if (options.length <= viewMoreLimit) return null;
        return <div className="view-more-container" onClick={handleViewClick}>{viewText}</div>
    }
 
    return <div className="filters-container">
        <div className="filter-label">{field}</div>
        <div className="filter-option-wrapper">
            {renderFilters()}
            {viewMore && renderViewText()}
        </div>
    </div>;
};

Related Components