Shared State
Prerequisite
This page assumes you’ve already initialized your Agent (Embedded | Overlay).
Overview
Shared State creates a two-way synchronization between your application's UI state (like a form or settings panel) and the AI agent. This powerful feature allows the agent to both read the current state of your UI in real-time and write changes back to it.
API Reference
The entire process is managed by two main methods on the agent instance.
shareState(key, state, handler)
shareState(key, state, handler)
This is the core method for establishing and updating the synchronized state. It should be called once on initialization and then again every time the user-side state changes.
Parameter | Type | Required | Description |
---|---|---|---|
key | string | Yes | A unique string identifier for this piece of state (e.g., "contact_form" ). |
state | object | Yes | A snapshot of the current UI state object (e.g., { name: "", email: "" } ). |
handler | (key: string, nextState: any) => void | No | Crucial for two-way sync. This parameter is optional, but required to allow the agent to push updates back to your UI. |
clearState(key)
clearState(key)
Tells the agent to stop tracking a piece of state. This is critical for cleanup when a component unmounts or the user navigates away, preventing memory leaks.
Parameter | Type | Required | Description |
---|---|---|---|
key | string | Yes | The unique string identifier for the state you wish to clear. |
React + TypeScript Example
This example shows how to synchronize a React form component's state with the agent using hooks.
import { useEffect, useRef, useState } from "react";
type FormState = {
name: string;
email: string;
company?: string;
};
interface Props {
agentKey: string;
}
export default function SharedStateForm({ agentKey }: Props) {
// 1. Local UI state is kept minimal.
const [form, setForm] = useState<FormState>({ name: "", email: "", company: "" });
// 2. The agent instance is created once and stored in a ref.
const agentRef = useRef<any | null>(null);
const stateKey = "contact_form";
// 3. `useEffect` handles the entire lifecycle: setup, subscription, and cleanup.
useEffect(() => {
// Initialize the agent
agentRef.current = window.eucera?.agent(agentKey);
// Agent -> UI: Define the handler to receive updates FROM the agent
const handleStateChange = (key: string, nextState: unknown) => {
if (key === stateKey) {
setForm(nextState as FormState); // Update local state
}
};
// Initial sync: Register the state key, initial data, and the handler
agentRef.current?.shareState(stateKey, form, handleStateChange);
// Cleanup function: Tell the agent to stop tracking on unmount
return () => {
agentRef.current?.clearState(stateKey);
agentRef.current = null;
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [agentKey]);
// 4. UI -> Agent: Call this on user input to keep the agent's snapshot fresh.
const updateField = <K extends keyof FormState>(key: K, value: FormState[K]) => {
const next = { ...form, [key]: value };
setForm(next);
// Send the fresh snapshot to the agent
agentRef.current?.shareState(stateKey, next);
};
// 5. Render your form inputs and call updateField on change.
return <>...</>;
}
Vanilla JS Example
This example demonstrates how to synchronize standard HTML form inputs without a framework.
<script>
// 1. Create the agent instance ONCE.
const agentKey = "YOUR_AGENT_KEY";
const agent = window.eucera?.agent(agentKey);
// 2. Choose a stable key for this piece of state.
const stateKey = "shipping_address";
// 3. Create helper functions to read from and write to the DOM.
const readUI = () => ({
fullName: document.getElementById("fullName")?.value || "",
street: document.getElementById("street")?.value || "",
city: document.getElementById("city")?.value || "",
postal: document.getElementById("postal")?.value || "",
});
const writeUI = (next) => {
if (!next || typeof next !== "object") return;
Object.entries(next).forEach(([k, v]) => {
const el = document.getElementById(k);
if (el) el.value = v ?? "";
});
};
// 4. Agent -> UI: This handler listens for agent-driven updates and writes them to the DOM.
const handleStateChange = (key, nextState) => {
if (key === stateKey) {
writeUI(nextState);
}
};
// 5. On page load, perform the initial sync.
agent?.shareState(stateKey, readUI(), handleStateChange);
// 6. UI -> Agent: Add event listeners to send updates to the agent on user input.
["fullName", "street", "city", "postal"].forEach((id) => {
const el = document.getElementById(id);
if (!el) return;
el.addEventListener("input", () => agent?.shareState(stateKey, readUI()));
});
// 7. Use `beforeunload` to clean up the state.
window.addEventListener("beforeunload", () => agent?.clearState(stateKey));
</script>