SDK

Page context.

The single most under-used feature of the SDK. Without context, the agent opens with a generic greeting. With context, it knows what record the user is looking at and can answer pointed questions about it.

Mount-time

The context prop

Captured at mount. Best for full-page-load navigation where each page has one record.

tsx
import { CopilotBubble } from "@onpilot/react";

<CopilotBubble
  identityToken={token}
  context={{
    recordType: "booking",
    recordId: booking.code,
    recordData: {
      customer: booking.customer.name,
      status: booking.status,
      moveDate: booking.moveDate,
    },
    url: pathname,
    title: document.title,
  }}
/>;

Type

Shape

ts
interface CopilotContext {
  recordType?: string;     // e.g. "booking", "customer", "deal"
  recordId?: string;       // your stable identifier
  recordData?: Record<string, unknown>; // arbitrary payload
  url?: string;            // current path
  title?: string;          // page title
}

recordType and recordId together identify the record. recordData is arbitrary JSON included verbatim in the agent's context window — don't put secrets, tokens, or sensitive PII in here.

SPA

useOnPilot().setContext()

The context prop is captured once. For client-side route changes (Next.js App Router navigation, React Router transitions), update the context dynamically with the hook.

tsx
import { useEffect } from "react";
import { useOnPilot } from "@onpilot/react";

export function BookingDetail({ booking }: { booking: Booking }) {
  const { setContext } = useOnPilot();

  useEffect(() => {
    setContext({
      recordType: "booking",
      recordId: booking.code,
      recordData: {
        customer: booking.customer.name,
        status: booking.status,
      },
    });
  }, [booking.code]);

  return <BookingFields booking={booking} />;
}

The hook returns { isOpen, isReady, open, close, toggle, setContext }.

useOnPilot() throws inside CopilotPanel. The headless component has no provider. Use CopilotInline, CopilotBubble, or CopilotSidebar if you need the hook.

Behavior

What the agent sees

recordType and recordId become searchable identifiers — the agent can look up "this record" without you describing it. recordData is included verbatim so the agent can quote fields back to the user. Context updates while the chat is open take effect on the next message.

Recipes

Common patterns

  • CRM record detail page — pass the deal/contact/account on context prop
  • SPA with route changes — call setContext() from each detail page's useEffect
  • Multi-step form — update context on each step transition
  • Tabs — call setContext() on tab change

Security

Don't put

  • API tokens, session tokens, refresh tokens
  • Passwords or password hashes
  • Card numbers or full SSNs
  • Anything you wouldn't put in a log line

If a field is sensitive, don't pass it. The agent infers what it needs from your tools and knowledge sources.