7. Pass context
An agent that knows the visitor is on the invoices page, on the pro plan, looking at invoice INV-2041, answers a different question from one that only sees “why was I charged twice”. Vars are how you tell it.
What vars are
Section titled “What vars are”Vars are a JSON object stored on the conversation thread and made available to
the agent’s code as meta.vars. Three layers merge, in this order:
- Agent variables, from the Security tab. The same for every conversation.
- Widget vars, from your page. Per visitor and per conversation, and they override the agent’s values.
- Canonical keys, injected by Urai:
thread_id,organization_id, anduser_id. These always win.
Inside a script the agent writes, they read as meta.vars.plan or
meta.vars.organization_id. The agent’s prompt lists the variable names it can
expect, so anything you pass consistently is worth naming in the instructions
too.
Keep vars small and non-secret. They travel from the browser and are stored on the thread, so a visitor can read them and can change them. Nothing here may decide what the agent is allowed to do. When the agent needs to call your API on the user’s behalf, pass a short-lived signed token your backend minted and verifies; see securing your app for the pattern.
Set them at creation
Section titled “Set them at creation”The initial vars seed the first thread the visitor creates:
<UraiChatWidget widgetToken="wgt_..." userId={currentUser.id} vars={{ plan: currentUser.plan, locale: "en-US", page: location.pathname }}/>With the script tag, use data-vars with a JSON object:
<script src="https://chat.app.urai.dev/api/widget/embed.js" data-widget-token="wgt_..." data-user-id="user_42" data-vars='{"plan":"pro","locale":"en-US"}'></script>Update them as the visitor moves
Section titled “Update them as the visitor moves”In React, changing the vars prop calls setVars on the active thread. The prop
is deep compared, so an inline object literal is fine:
function App() { const location = useLocation();
return ( <UraiChatWidget widgetToken="wgt_..." userId={currentUser.id} vars={{ plan: currentUser.plan, page: location.pathname }} /> );}Imperatively, through the controller or the global:
// Update the active thread, or buffer for the next one if none exists yetUraiChat.setVars({ page: location.pathname, record_id: recordId });
// ClearUraiChat.setVars(null);setVars replaces the widget vars rather than merging into them, so send the
whole object you want the thread to have.
Handle identity changes
Section titled “Handle identity changes”When the visitor signs in, signs out, or switches account, set the user rather than the vars. Changing the id resets the conversation, which is what you want: the previous visitor’s thread should not be visible to the next one.
UraiChat.setUser({ id: currentUser.id, vars: { plan: currentUser.plan, locale: currentUser.locale },});In React, the same thing happens by changing the userId prop.
Start a fresh conversation
Section titled “Start a fresh conversation”Sometimes the context changes enough that continuing the old thread is wrong, such as when the visitor opens a different record. Threads are created lazily on the first message, so starting one on every route change costs nothing:
UraiChat.startConversation({ page: location.pathname, order_id: orderId });A pattern that works
Section titled “A pattern that works”Set identity once at sign-in, keep a small set of vars current on navigation, and start a fresh conversation only when the subject changes:
useEffect(() => { if (!user) return; widget.current?.setUser({ id: user.id, vars: { plan: user.plan } });}, [user?.id]);
useEffect(() => { widget.current?.setVars({ plan: user.plan, page: location.pathname });}, [location.pathname]);Then use them in your library and your instructions:
The user's current page is in `meta.vars.page` and their plan in`meta.vars.plan`. On `/billing`, assume the question is about a charge beforeasking what they mean.Check before moving on
Section titled “Check before moving on”Open the widget on two different pages of your app and ask “what am I looking
at”. The answers should differ. In the console thread you can read the code the
agent ran, so confirm it picked up meta.vars.page rather than asking.
Next: handle commands.