The Docent component
Every prop of the Docent component with its type and default, the hooks it provides, the events it emits, and the handle it puts on React context.
<Docent> from @usedocent/react mounts the guide and gives everything under it the handle.
Props
| Prop | Type | Default | What it does |
|---|---|---|---|
appId | string | required | The app this session belongs to, from the Console. |
publishableKey | string | required | dk_pub_.... Ships in the browser and is restricted to the environment's allowed origins. |
apiUrl | string | required | Origin of the Docent API, normally https://api.usedocent.com. |
user | { id: string; traits?: Record<string, string | number | boolean> } | required | The only identity the guide gets. id keys memory and placement. |
userToken | string | none | An HS256 JWT your server signs with the environment's signing secret. When it verifies, the session is marked verified. |
router | RouterAdapter | pushState fallback | How the guide navigates. See the framework guides. |
presence | Partial<Omit<PresenceOptions, 'appId' | 'user'>> | none | Overrides for the mascot, such as palette and mascot. appId and user are set for you. |
loadPresence | (slug: string) => Promise<MascotFactory> | none | Loads the presence the owner chose, by library slug. Omitted, every session gets Dot. |
loadAudio | (vendor: 'telnyx' | 'openai') => Promise<AudioModule> | none | Loads the voice client for the vendor this session was granted. Omitted, startVoice() rejects with voice_unavailable. |
nudges | NudgeOptions | false | on | Proactive, caption-only prompts with a per-session budget. false turns them off. |
voice | 'tap' | 'off' | 'off' | 'tap' starts voice on the user's own first tap of the presence, and never before it. |
onEvent | (event: DocentEvent) => void | none | Read live on every render, so an inline arrow is fine. |
debug | boolean | false | Puts the handle on window.__docent. |
children | ReactNode | none | Your app. It has to be children, not a sibling. |
fetchImpl and WebSocketImpl also exist, for tests that need to stand in for the network.
The session is keyed on appId, publishableKey, apiUrl, user.id and userToken. Change
one of those and the guide tears down and mints a new session. Everything else, the router
adapter, loadAudio, loadPresence and onEvent included, is read live, so an inline object or
arrow function does not remount anything.
Events
onEvent and useDocentEvent receive the same four:
| Event | Fields | When |
|---|---|---|
handoff | reason, route, transcript | The guide passed the user to human support. The transcript is masked. |
open_docs | url, title? | The guide offered a documentation link. |
goal_done | goalKey | A goal's done condition was met. |
error | code, message | Something failed. Codes include mint_failed, voice_failed, presence_failed and whatever the server sent. |
<Docent
// ...
onEvent={(event) => {
if (event.type === 'handoff') openIntercom(event.transcript)
}}
/>Hooks
All of them are from @usedocent/react and all of them must be called under the component.
| Hook | Returns | Notes |
|---|---|---|
useDocent() | DocentHandle | null | Null until the guide has mounted, which is one effect after first paint. |
useDocentOrThrow() | DocentHandle | Throws instead of returning null, for call sites that would rather fail loudly. |
useDocentEvent(cb) | void | Subscribes without wiring an effect. The callback is held in a ref, so an inline arrow neither resubscribes nor goes stale. |
useDocentState() | DocentState | null | The mascot's current state, polled every 200ms. |
useDocentTrack() | (event: string, payload?) => void | Safe to call before the guide has mounted. |
The handle
What useDocent() returns:
| Member | Type | What it is |
|---|---|---|
presence | PresenceHandle | The mascot and its overlay. |
tools | Tools | The page tools: spotlight, point, scroll_to, navigate, act, plus clear and destroy. |
sessionId | string | null | Null until the session is minted. |
ready | Promise<void> | Resolves when minting has finished, successfully or not. |
ask(text) | Promise<void> | Sends a typed turn, as the composer does. |
track(event, payload?) | void | Reports a goal event. |
on(cb) | () => void | Subscribes. Returns the unsubscribe. |
startVoice() | Promise<void> | Asks for microphone consent the first time, then opens a call. |
endVoice() | Promise<void> | Hangs up and releases the microphone. |
destroy() | void | Tears everything down. The component calls this on unmount. |
One example
'use client'
import { useDocent, useDocentEvent, useDocentTrack } from '@usedocent/react'
export const Toolbar = () => {
const docent = useDocent()
const track = useDocentTrack()
useDocentEvent((event) => {
if (event.type === 'goal_done') confetti(event.goalKey)
})
return (
<button
onClick={() => {
track('asked_for_help')
void docent?.ask('how do I invite a teammate')
}}
>
Ask the guide
</button>
)
}