Passive context is a continuously updated description of what the user is currently viewing — which page, which resource, what filters, etc. The assistant uses it to ground the conversation: when the user asks “why did this drop in March?”, the context is what makes “this” mean the revenue chart they’re looking at.
Any component in your app can declare context declaratively, so you can set it where the state naturally lives. The SDK assembles the full picture and keeps Claritype up to date.
To declare context, call this hook from any component under the provider. While the component is mounted, its entry is part of the context; when it unmounts, the entry is withdrawn automatically:
import { useClaritypeContextSource } from "@claritype/embed-react";
function DashboardPage({ dashboardId, filters }: DashboardPageProps) {
useClaritypeContextSource({
type: "dashboard",
id: dashboardId,
state: { filters },
});
return /* … */;
}
Pass null or undefined to contribute nothing for now — useful while data
is loading or nothing is selected:
useClaritypeContextSource(selectedRow ? { type: "selection", id: selectedRow.id } : null);
ContextEntry shapeinterface ContextEntry {
type: string;
id?: string;
state?: Record<string, unknown>;
}
| Field | Description |
|---|---|
type |
What kind of thing this describes: "dashboard", "workspace", "selection", … Your Claritype project configuration can provide more information about this vocabulary to the assistant. |
id |
Which specific thing? Omit for singletons (e.g. there’s only one settings page). |
state |
Arbitrary view state — filters, date ranges, sort order. Anything that changes what the user is actually seeing. |
Because each component declares only its own slice, the SDK assembles context from all the components that declare it:
function AppShell({ workspace }) {
useClaritypeContextSource({ type: "workspace", id: workspace.id });
return <Outlet />;
}
function DashboardPage({ dashboardId, filters }) {
useClaritypeContextSource({ type: "dashboard", id: dashboardId, state: { filters } });
return <Panels />;
}
function ChartPanel({ chartId, selection }) {
useClaritypeContextSource(
selection ? { type: "selection", id: chartId, state: { selection } } : null
);
return /* … */;
}
With all three mounted, the assistant sees the workspace, the dashboard with its filters, and the current selection. Navigate away from the dashboard and its entries retract with it. Context can’t go stale by omission, because a component that isn’t mounted isn’t describing anything.
There’s no separate “update” call: change the entry you pass (new filters, new id) and the context updates. Think of it like any other declarative React output: describe the current state on every render and the SDK handles the rest.
Behind the scenes, the SDK:
The assistant only reacts to context changes when the user sends a message or uses
discuss to trigger a response.
Entries are serialized to JSON — both to detect changes and to send. Pass plain data:
Date objects become ISO strings; prefer converting explicitly so the
format is under your control.undefined fields and functions are dropped.Map, Set, and class instances don’t survive serialization — convert to
arrays/plain objects first.BigInt)
contributes nothing; the SDK warns in the console rather than throwing.Aim for what a knowledgeable colleague looking over the user’s shoulder would
need: identifiers the backend can resolve (that’s what id and typed entries
are for) plus the view state that changes interpretation (filters, date
ranges, groupings).
Think about the utility of what you’re sending, especially when building
arbitrary state objects. Extraneous data won’t help the assistant’s
performance. Skip very large objects or high-churn data (e.g. raw datasets,
mouse positions, scroll offsets). For a specific piece of data the user is
explicitly asking about, use
discuss with a snapshot
instead.
Context entries are persisted with the conversation, governed by your Claritype organization’s conversation retention policy.