AI-Powered Shopping Assistant for E-Commerce
Website · Dashboard · Quick Start · Packages
Dialog is an AI assistant designed to boost e-commerce sales by providing intelligent product recommendations and seamless customer interactions. This monorepo contains the official SDK and UI component libraries for integrating Dialog into your web applications.
- AI-Powered Suggestions - Automatically generate relevant product questions to engage customers
- Multi-Framework Support - Native components for Vue 3 and React 19
- Customizable Theming - Full control over colors, typography, and styling
- Built-in Analytics - Track user interactions, add-to-cart events, and conversions
- TypeScript First - Complete type definitions for excellent developer experience
- Lightweight - Minimal bundle size with tree-shaking support
This monorepo contains the following packages:
| Package | Version | Description |
|---|---|---|
@askdialog/dialog-sdk |
Core SDK with AI assistant functionality | |
@askdialog/dialog-vue |
Vue 3 component library | |
@askdialog/dialog-react |
React 19 component library |
- Node.js >= 22
- API Key - Get your API key from Dialog Dashboard
npm install @askdialog/dialog-sdk @askdialog/dialog-vue<script setup lang="ts">
import { Dialog, type SimplifiedProduct } from '@askdialog/dialog-sdk'
import { DialogProductBlock } from '@askdialog/dialog-vue'
import '@askdialog/dialog-vue/style.css'
const client = new Dialog({
apiKey: 'YOUR_API_KEY',
locale: 'en',
callbacks: {
addToCart: async ({ productId, quantity, variantId }) => {
// Handle add to cart
},
getProduct: async (productId, variantId): Promise<SimplifiedProduct> => {
// Fetch and return product data matching SimplifiedProduct type
return {
id: productId,
title: 'Product Name',
handle: 'product-handle',
descriptionHtml: '<p>Product description</p>',
url: 'https://store.com/products/product-handle',
totalInventory: 100,
featuredImage: {
url: 'https://store.com/images/product.jpg',
},
variants: [
{
id: variantId || 'variant-1',
displayName: 'Default',
inventoryQuantity: 50,
price: '29.99',
currencyCode: 'USD',
compareAtPrice: '39.99',
url: 'https://store.com/products/product-handle?variant=variant-1',
selectedOptions: [
{ name: 'Size', value: 'Medium' },
{ name: 'Color', value: 'Blue' },
],
image: {
url: 'https://store.com/images/variant.jpg',
},
},
],
options: [
{ id: 'option-1', name: 'Size', position: 1, values: ['Small', 'Medium', 'Large'] },
{ id: 'option-2', name: 'Color', position: 2, values: ['Red', 'Blue', 'Green'] },
],
}
},
},
})
</script>
<template>
<DialogProductBlock
:client="client"
product-id="product-123"
product-title="Product Name"
/>
</template>npm install @askdialog/dialog-sdk @askdialog/dialog-reactimport { Dialog, type SimplifiedProduct } from '@askdialog/dialog-sdk'
import { DialogProductBlock } from '@askdialog/dialog-react'
import '@askdialog/dialog-react/style.css'
const client = new Dialog({
apiKey: 'YOUR_API_KEY',
locale: 'en',
callbacks: {
addToCart: async ({ productId, quantity, variantId }) => {
// Handle add to cart
},
getProduct: async (productId, variantId): Promise<SimplifiedProduct> => {
// Fetch and return product data matching SimplifiedProduct type
return {
id: productId,
title: 'Product Name',
handle: 'product-handle',
descriptionHtml: '<p>Product description</p>',
url: 'https://store.com/products/product-handle',
totalInventory: 100,
featuredImage: {
url: 'https://store.com/images/product.jpg',
},
variants: [
{
id: variantId || 'variant-1',
displayName: 'Default',
inventoryQuantity: 50,
price: '29.99',
currencyCode: 'USD',
compareAtPrice: '39.99',
url: 'https://store.com/products/product-handle?variant=variant-1',
selectedOptions: [
{ name: 'Size', value: 'Medium' },
{ name: 'Color', value: 'Blue' },
],
image: {
url: 'https://store.com/images/variant.jpg',
},
},
],
options: [
{ id: 'option-1', name: 'Size', position: 1, values: ['Small', 'Medium', 'Large'] },
{ id: 'option-2', name: 'Color', position: 2, values: ['Red', 'Blue', 'Green'] },
],
}
},
},
})
function ProductPage() {
return (
<DialogProductBlock
client={client}
productId="product-123"
productTitle="Product Name"
/>
)
}npm install @askdialog/dialog-sdkimport { Dialog, type SimplifiedProduct } from '@askdialog/dialog-sdk'
const client = new Dialog({
apiKey: 'YOUR_API_KEY',
locale: 'en',
callbacks: {
addToCart: async ({ productId, quantity, variantId }) => {
// Handle add to cart
},
// Optional: sets a line the assistant added to `quantity` (absolute)
changeCartQuantity: async ({ productId, quantity, variantId }) => {
// Set the cart line to `quantity`
},
getProduct: async (productId, variantId): Promise<SimplifiedProduct> => {
// Return product data - see type definition below
},
},
})
// Fetch AI-generated suggestions for a product
const suggestions = await client.getSuggestions('product-123')
// Send a message to the assistant
await client.sendProductMessage({
message: 'What are the dimensions?',
productId: 'product-123',
})The getProduct callback must return a SimplifiedProduct object. This is essential for Dialog to function correctly.
interface SimplifiedProduct {
id: string // Unique product identifier
title: string // Product display name
handle: string // URL-friendly product slug
descriptionHtml?: string // HTML product description
url?: string // Full product page URL
totalInventory: number // Total stock across all variants
featuredImage?: {
url?: string // Main product image URL
} | null
variants: SimplifiedProductVariant[] // Product variants (sizes, colors, etc.)
options?: SimplifiedProductOption[] // Available product options
}interface SimplifiedProductVariant {
id: string // Unique variant identifier
displayName?: string // Variant display name
inventoryQuantity?: number // Stock count for this variant
price: string // Current price (e.g., "29.99")
currencyCode: string // ISO currency code (e.g., "USD", "EUR")
compareAtPrice?: string | null // Original price for sale items
url?: string // Direct URL to this variant
selectedOptions?: {
name: string // Option name (e.g., "Size")
value: string // Selected value (e.g., "Medium")
}[]
image?: {
url?: string // Variant-specific image URL
} | null
}interface SimplifiedProductOption {
id: string // Option identifier
name: string // Option name (e.g., "Size", "Color")
position: number // Display order
values: string[] // Available values (e.g., ["S", "M", "L"])
}The main component for displaying AI-powered product suggestions.
| Prop | Type | Required | Description |
|---|---|---|---|
client |
Dialog |
Yes | Dialog SDK instance |
productId |
string |
Yes | Product identifier |
productTitle |
string |
Yes | Product display name |
selectedVariantId |
string |
No | Currently selected variant |
enableInput |
boolean |
No | Show input field (default: true) |
A standalone input component for asking questions.
| Prop | Type | Required | Description |
|---|---|---|---|
client |
Dialog |
Yes | Dialog SDK instance |
productId |
string |
Yes | Product identifier |
productTitle |
string |
Yes | Product display name |
Customize the appearance by passing a theme object to the SDK:
const client = new Dialog({
apiKey: 'YOUR_API_KEY',
locale: 'en',
theme: {
backgroundColor: '#ffffff',
primaryColor: '#007bff',
ctaTextColor: '#ffffff',
ctaBorderType: 'rounded', // 'straight' | 'rounded'
capitalizeCtas: false,
fontFamily: 'Inter, sans-serif',
title: {
fontSize: '18px',
color: '#1a1a1a',
},
description: {
fontSize: '14px',
color: '#666666',
},
content: {
fontSize: '14px',
color: '#333333',
},
},
callbacks: {
// ...
},
})Track user interactions for analytics:
// Track add-to-cart events
client.registerAddToCartEvent({
productId: 'product-123',
variantId: 'variant-456',
quantity: 1,
price: 29.99,
})
// Track checkout events
client.registerSubmitCheckoutEvent({
productId: 'product-123',
variantId: 'variant-456',
quantity: 1,
price: '29.99',
})
// Listen to assistant events
client.onAssistantEvent((event) => {
console.log('Assistant event:', event)
})# Clone the repository
git clone https://github.com/askdialog/dialog-components.git
cd dialog-components
# Install dependencies
pnpm install
# Build all packages
pnpm build| Command | Description |
|---|---|
pnpm build |
Build all packages |
pnpm dev |
Start Vue example dev server |
pnpm dev:react-example |
Start React example dev server |
pnpm lint |
Lint all packages |
pnpm lint:fix |
Fix linting issues |
pnpm test |
Run all tests |
pnpm clean |
Clean all build outputs |
pnpm graph |
View dependency graph |
dialog-components/
├── packages/
│ ├── sdk/ # @askdialog/dialog-sdk - Core SDK
│ ├── vue/ # @askdialog/dialog-vue - Vue 3 components
│ ├── react/ # @askdialog/dialog-react - React components
│ ├── vue-example/ # Vue development app
│ └── react-example/ # React development app
├── .changeset/ # Version management
├── nx.json # Nx configuration
├── pnpm-workspace.yaml # pnpm workspace config
└── tsconfig.base.json # Shared TypeScript config
- Build System: Nx + Vite
- Package Manager: pnpm
- Languages: TypeScript 5.9
- Versioning: Changesets
- Linting: ESLint 9 + Prettier
We welcome contributions! Please see our contributing guidelines for more details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
When making changes that should be released:
pnpm changesetFollow the prompts to describe your changes.
MIT License - see LICENSE for details.