Activity
Lightweight session activity tracking: product views, category views, recommendations, and contextual messages. Calls are fire-and-forget where possible; failures never bubble into your UI.
Track a product view
Synchronous, returns nothing. Drop it into a product page render or hover handler; the SDK queues and POSTs in the background.
client.activity.trackProductView('prod_xxx', {
productName: 'Studio Tee (Natural)',
categoryId: 'cat_apparel',
price: '29.99',
pagePath: '/products/studio-tee-natural', // defaults to window.location.pathname
})
client.activity.trackCategoryView('cat_apparel', {
categoryName: 'Apparel',
})Read activity state
Returns the server's view of the current session: viewed products, intent classification, active messages, and any active incentive.
const r = await client.activity.getState()
if (!r.ok) {
console.error(r.error.code, r.error.message)
return
}
const { activity, intent, messages, incentive } = r.value
console.log(intent) // e.g. 'browse', 'compare', 'ready_to_buy'
console.log(activity?.viewed_products.length)
console.log(messages) // SessionMessage[]
console.log(incentive) // { template_id, agent_id } | nullGet recommendations
const r = await client.activity.getRecommendations({
location_id: 'loc_main',
limit: 6,
})
if (r.ok) {
for (const rec of r.value.recommendations) {
console.log(rec.product.id, rec.product.name, rec.reason)
}
console.log(r.value.intent)
}Dismiss a message
Pass the message code (NOT a database id). The server keys dismissals by code so the same logical message stays dismissed across sessions.
const r = await client.activity.dismissMessage('cart_abandonment_15min')
if (r.ok) {
console.log(r.value.dismissed) // 'cart_abandonment_15min'
console.log(r.value.messages.length) // remaining undismissed messages
}Render contextual messages
'use client'
import { useEffect, useState } from 'react'
import { useCimplifyClient } from '@cimplify/sdk/react'
import type { SessionMessage } from '@cimplify/sdk'
export function Banners() {
const client = useCimplifyClient()
const [messages, setMessages] = useState<SessionMessage[]>([])
useEffect(() => {
let active = true
client.activity.getState().then((r) => {
if (active && r.ok) setMessages(r.value.messages)
})
return () => { active = false }
}, [client])
async function dismiss(code: string) {
const r = await client.activity.dismissMessage(code)
if (r.ok) setMessages(r.value.messages)
}
return (
<ul>
{messages.map((m) => (
<li key={m.code}>
<span>{m.text}</span>
{m.dismissible && <button onClick={() => dismiss(m.code)}>×</button>}
</li>
))}
</ul>
)
}Method reference
| Method | Returns |
|---|---|
trackProductView(id, opts?) | void |
trackCategoryView(id, opts?) | void |
getState() | Result<ActivityStateResponse> |
getRecommendations(opts?) | Result<ActivityRecommendationsResponse> |
dismissMessage(code) | Result<DismissMessageResponse> |
Related
-
Catalogue Source for the products you'll track + recommend
-
Cart Cart state feeds the intent classifier
-
Support Companion chat surface for the same session
-
Result<T, E> Return shape for the async methods
Subscriptions
Read and manage the customer's recurring orders. Subscriptions are created during checkout when a billing plan is attached to a cart item; this surface lets you list them, pause / resume them, skip the next renewal, and cancel.
FX
Spot rates and locked quotes for cross-currency checkout. `checkout.process` will lock a quote for you automatically when `pay_currency` differs from the cart currency; call `fx.lockQuote` directly only when you need the rate ahead of time (e.g. to display "Pay in USD" before the customer commits).