The SDK has two components. <ClaritypeProvider> configures your integration
once for the whole app; <ClaritypeSurface> places one embedded Claritype
component into your layout. This page is the full reference for both.
<ClaritypeProvider>Wrap your app (or at least everything that uses Claritype) in a single provider. It establishes your integration’s identity, holds the shared action handlers, and makes the hooks and surfaces below it work.
import { ClaritypeProvider } from "@claritype/embed-react";
<ClaritypeProvider
origin="https://claritype.acme.example"
themeMode={colorMode}
handlers={handlers}
>
<YourApp />
</ClaritypeProvider>;
| Prop | Type | Required | Description |
|---|---|---|---|
orgId |
string |
no | Your Claritype organization ID. Normally omitted: Claritype resolves the org from the signed-in user. Selects among the orgs the user can already reach, never grants access, and requires project. Fixed while the provider is enabled. |
project |
string |
no | Your Claritype project ID. Omit it to use the organization’s default project. Fixed while the provider is enabled. |
origin |
string |
yes | The origin that serves your embedded components, provided by Claritype for your integration. A bare http(s) origin like https://claritype.acme.example — a path, query, fragment, or credentials throws when the provider is enabled. Fixed while the provider is enabled. |
connection |
string |
no | Identity-provider connection your users authenticate through, named by Claritype for your integration. Set it when your app federates its own users: the assistant sends them straight to that provider, so an already-signed-in user reaches it without a login screen. Omit it when your users have Claritype logins of their own. Fixed while the provider is enabled. |
handlers |
ActionRegistry |
no | Action handlers the assistant can invoke. See Actions. |
themeMode |
"light" \| "dark" |
no | Your app’s current color mode. Defaults to "light". Updates apply live. |
debug |
boolean |
no | Log SDK diagnostics and integration warnings to the console. Defaults to false. |
enabled |
boolean |
no | Whether Claritype is on. Defaults to true. Bind it to your gate (feature flag, entitlement, sign-in); see Turning Claritype on and off. |
orgId, project, and origin are read when the
provider’s client is created — at mount, or when enabled turns on. To
point at a different project, remount the provider (e.g. with a key),
which starts a fresh session.themeMode is live. It’s the one prop designed to change over time —
bind it to your app’s color mode and every surface follows along. The look
of the embedded component (colors, fonts) is configured in your Claritype
project; at runtime this allows switching between light and dark variants.handlers object
every render; handler bodies always see your latest props and state. The
set of action keys and versions, though, is fixed when the client is
created — see
Actions."use client" directive for Next.js App Router.Render the provider unconditionally and pass your gate as enabled. Toggling
it never changes the shape of your tree, so your own components don’t remount.
enabled is false nothing connects to Claritype: no iframe, no
listeners, no network traffic. origin isn’t checked yet, so it may be
empty. Surfaces render their empty container; useClaritype() reports
enabled: false and canDiscuss: false, and discuss() does nothing.
Context you declare with useClaritypeContextSource is held and sent once
Claritype turns on.handlers. Mounted surfaces load in place and
pick up their current revealed.Hooks and surfaces rendered with no provider at all still throw — that’s a wiring mistake, not a gate.
<ClaritypeSurface>A surface is one embedded Claritype component living wherever you choose in your
layout. <ClaritypeSurface> renders a container <div> and mounts the component
into it using an <iframe>. Use it anywhere within the provider.
import { ClaritypeSurface, Component } from "@claritype/embed-react";
<ClaritypeSurface
component={Component.Sidebar}
discussTarget
revealed={open}
onReveal={() => setOpen(true)}
className="fill"
/>;
| Prop | Type | Required | Description |
|---|---|---|---|
component |
Claritype SDK Component (see below) |
yes | Which embedded component this surface renders. Fixed for the surface’s lifetime. |
discussTarget |
boolean |
no | Make this the surface that discuss() routes to. Fixed for the surface’s lifetime. If omitted from all surfaces, routing is automatic. |
revealed |
boolean |
no | Declaratively drive this surface’s visibility (see below). |
onReveal |
() => void \| Promise<void> |
no | Called when the SDK needs this surface visible — open your panel here (see below). |
onReady |
() => void |
no | Called once, when the component has connected and the session is live. |
onHandshakeFailed |
(failure: HandshakeFailedPayload) => void |
no | Called if the component can’t serve this session. Ends this surface’s lifecycle. |
frameUrl |
string |
no | Full component URL override, for local development and testing. Takes precedence over the provider’s origin. Fixed for the surface’s lifetime. |
className |
string |
no | Class for the container <div>. Use to size and position the surface. |
style |
CSSProperties |
no | Inline styles for the container <div>. |
Component enumerates the embedded components Claritype serves:
| Value | String form | Description |
|---|---|---|
Component.Sidebar |
"sidebar" |
The conversational sidebar. |
More components will be added over time.
The embedded component fills the container <div> completely; the SDK never
positions or floats anything. Give the container real dimensions via
className/style (or its parent’s layout) — the surface is exactly as big
as the box you give it.
The most important rule of surface lifecycle: hide, don’t unmount. When a surface unmounts, the embedded component is torn down, and remounting it later starts it from scratch — the in-progress conversation state is dropped. So:
// ✅ Keep it mounted; hide the container.
<aside hidden={!open}>
<ClaritypeSurface component={Component.Sidebar} revealed={open} … />
</aside>
// ❌ Don't conditionally render it.
{open && <ClaritypeSurface component={Component.Sidebar} … />}
The same applies to tab libraries and routers: use their keepMounted /
forceMount options for the panel a surface lives in. With debug on, the
SDK warns in the console when it detects a surface’s container leaving the
DOM.
Ordinary re-renders of your tree are fine — only a real unmount (or a remount
caused by a changed key) resets the surface. React StrictMode’s
double-invoke in development is absorbed and won’t reload anything.
revealed and onRevealYour app owns whether a surface is visible; the SDK just needs to be kept in the loop (so the component can, say, pause work while hidden), and asks you to show the surface when the user calls for it within your app. Two props cover this:
revealed — declarative visibility. Bind it to the same state that
shows/hides the container, and the SDK tells the component whenever the
value changes. It’s replayed automatically when the component (re)connects,
so a surface that starts open, or reloads, comes up in sync. If you never
pass revealed, the SDK simply doesn’t track visibility for you.onReveal — A callback that fires when the SDK wants to show the
surface. In practice that’s a discuss() call, which
implies opening the panel. Do whatever your layout needs, e.g. set your open
state or switch to the right tab. It may be async. Make it idempotent, as it
can fire while the surface is already visible.Here’s an example using onReveal and revealed when they apply to the
same state:
const [open, setOpen] = useState(false);
<ClaritypeSurface
component={Component.Sidebar}
discussTarget
revealed={open} // your state drives the component's visibility…
onReveal={() => setOpen(true)} // …and discuss can open the panel
/>;
When a surface mounts, the embedded component loads and connects to the SDK — the handshake. Two callbacks report how that goes:
onReady fires once, when the handshake completes and the session is
live. Useful for logging or deferring UI that depends on the assistant.
For a reactive “is it ready” value you can render against, use
useClaritype().canDiscuss instead.onHandshakeFailed fires if the component reports it cannot serve this
session. This is final for the surface. The failure has a code and a
human-readable message (diagnostic; not necessarily suitable to show end
users verbatim):code |
Meaning |
|---|---|
"context_missing" |
Claritype couldn’t work out which org or project to load: you didn’t name it, and the signed-in user has no default for it. |
"not_found" |
The org or project doesn’t exist. |
"unauthorized" |
The current user isn’t allowed to access this project. |
"unknown" |
Anything else. |
A failed surface is a good place to fall back gracefully — hide the panel and
the affordances that open it. If the Claritype origin is unreachable
altogether, the surface simply never becomes ready: no errors propagate into
your app, and canDiscuss stays false, which is
your signal to keep Claritype affordances hidden.
frameUrlframeUrl overrides the URL the surface loads, verbatim. Normally the SDK
derives it from the provider’s origin, the component, and the org and
project when you pass them; frameUrl bypasses that entirely. You’d use it to point a
surface at a local or staging deployment during development. Like
component, it’s read once at mount.