Web SDKs

React / Next.js

@primoia/vocall-react -- Hooks, Context, SSR-safe

React / Next.js SDK

The React SDK provides a context provider, hooks, and pre-built components for integrating Vocall into React 18+ and Next.js applications.

Installation

npm install @primoia/vocall-react

Peer dependencies: react >=18, react-dom >=18


VocallProvider

Wrap your application (or layout) with VocallProvider to make the client available to all hooks.

// app/layout.tsx
import { VocallProvider } from '@primoia/vocall-react';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <VocallProvider url="wss://engine.example.com/connect" token="my-token">
          {children}
        </VocallProvider>
      </body>
    </html>
  );
}

useVocall

Returns the core client state and control methods.

import { useVocall } from '@primoia/vocall-react';

const { client, status, messages, connected, sessionId, sendText, connect, disconnect, clearMessages } = useVocall();

| Property | Type | Description | |---|---|---| | client | VocallClient | Underlying client instance for advanced use. | | status | VocallStatus | Current engine status (disconnected, idle, listening, recording, thinking, speaking, executing). | | messages | Message[] | Chat message history. | | connected | boolean | Whether the WebSocket is connected. | | sessionId | string \| null | Active session identifier. | | sendText | (text: string) => void | Send a text message to the engine. | | connect | () => void | Open the WebSocket connection. | | disconnect | () => void | Close the connection. | | clearMessages | () => void | Clear the local message history. |


useVocallField

Binds a DOM element to a manifest field so the engine can read and write its value.

const { ref, registered } = useVocallField(screenId, fieldId, options?);

| Parameter | Type | Description | |---|---|---| | screenId | string | The screen identifier from your manifest. | | fieldId | string | The field identifier from your manifest. | | options | object? | Optional overrides (see below). |

Options:

| Option | Type | Default | Description | |---|---|---|---| | getValue | () => string | reads .value | Custom getter for the element's current value. | | setValue | (v: string) => void | sets .value | Custom setter to update the element. |

Attach ref to the target element. registered is true once the field has been bound.


useVocallAction

Registers a callback that the engine can invoke by action identifier.

useVocallAction(screenId, actionId, callback);

| Parameter | Type | Description | |---|---|---| | screenId | string | The screen identifier. | | actionId | string | The action identifier. | | callback | () => void | Function executed when the engine triggers this action. |


Built-in Components

VocallChat

A ready-made chat panel that renders messages and provides a text input.

| Prop | Type | Default | Description | |---|---|---|---| | position | 'left' \| 'right' | 'right' | Side of the screen. | | title | string | 'Vocall' | Header title. | | placeholder | string | 'Type a message...' | Input placeholder text. | | open | boolean | false | Controlled open state. | | onToggle | (open: boolean) => void | -- | Called when the user opens or closes the chat. | | className | string | -- | Additional CSS class for the container. |

VocallFab

A floating action button that toggles the chat panel or triggers voice input.

VocallStatusPill

A small badge that displays the current VocallStatus as a colored pill.


Full Example

'use client';

import { useVocall, useVocallField, useVocallAction, VocallChat, VocallFab } from '@primoia/vocall-react';

export default function InvoicePage() {
  const { status, messages, sendText } = useVocall();

  const clientName = useVocallField('invoice', 'clientName');
  const amount     = useVocallField('invoice', 'amount', {
    getValue: () => document.getElementById('amount-input')?.dataset.raw ?? '',
    setValue: (v) => {
      const el = document.getElementById('amount-input') as HTMLInputElement;
      if (el) el.value = formatCurrency(v);
    },
  });

  useVocallAction('invoice', 'submit', () => {
    console.log('Engine triggered submit');
  });

  return (
    <div>
      <h1>Emitir NFS-e</h1>

      <label>Client Name</label>
      <input ref={clientName.ref} placeholder="Client name" />

      <label>Amount</label>
      <input ref={amount.ref} id="amount-input" placeholder="0.00" />

      <p>Status: {status}</p>

      <VocallChat title="Invoice Assistant" position="right" />
      <VocallFab />
    </div>
  );
}

function formatCurrency(value: string): string {
  const num = parseFloat(value);
  return isNaN(num) ? value : num.toFixed(2);
}

Manifest Structure

Field and action identifiers must match your application manifest. See the Manifest Reference for details.