Skip to main content
This guide walks you through integrating the Form filling SDK in a React 18+ application. You create SukiAuthManager and FormFillingClient once inside useMemo, wrap your tree with FormFillingProvider, and render FormFilling when the clinician opens Form filling.

Prerequisites

Before you start:
  • Install @suki-sdk/form-filling-react and @suki-sdk/core (Form filling SDK v0.1.0-beta.3 or later for dynamic forms).
  • Get your partnerId from Partner onboarding. Pass a partnerToken (JWT from your identity provider) with that Partner ID to sign in.
  • Decide which forms to fill: Suki Medical form templates (ask Suki support for the template IDs), your own form schema, or both. See Dynamic Form filling.
  • Have an encounter ID ready to pass as correlation_id.
  • Run the app over HTTPS, with microphone access, and a container with height for the Form filling UI.
For webhooks and CSP, see Prerequisites.

Integration pattern

Create auth and the client once per page inside useMemo. Mount FormFilling only when the clinician is ready to open Form filling.

Suki Auth Manager

One SukiAuthManager after the partner token is available.

Form Filling Client

One FormFillingClient in useMemo. Reuse it for every session on that page.

FormFillingProvider

Wrap the part of your tree that renders FormFilling.

Conditional FormFilling

Mount FormFilling only while Form filling should be open.
Do not run new FormFillingClient(...) on every render. Use useMemo with stable dependencies.

Install the packages

Step 1: Style the container

React renders the hosted UI inside .suki-form-filling. Give that container explicit height, or the iframe looks blank.
CSS
Refer to Configuration for recommended CSS.

Step 2: Create auth manager and client in useMemo

Create both objects once per page inside useMemo. Optionally wire onError on the client for configuration and runtime errors.
React
Refer to Authentication for provider fields and other sign-in options.

Step 3: Wrap with FormFillingProvider

Pass the client from Step 2 into FormFillingProvider. Every component that renders FormFilling must be a child of that provider.
React
You can place FormFillingProvider at app root or only around the encounter screen that needs Form filling.

Step 4: Render FormFilling when the clinician opens Form filling

Use state (for example isFormOpen) so FormFilling mounts only while Form filling should be visible. When it unmounts, the SDK tears down the hosted UI. Pass the same session fields you would pass to client.start(), except rootElement (React supplies the container):
  • forms or form_template_ids: Required At least one form after resolve. Prefer forms for Suki template IDs, your own schema, or both. form_template_ids is deprecated, but still works when forms is omitted.
  • correlation_id: Optional Your encounter or appointment ID. Strongly recommended so results map to the correct record.
  • onSubmit: Required Called when structured JSON is ready after processing, not when the clinician taps submit. Receives a FormFillingResult.
  • onReady, onCancel: Optional.
  • onBackgroundSubmit: Optional React only. Results for a superseded session while the iframe is still open.
React

Callbacks and events

Your app needs to know when Form filling is ready, when structured results arrive, and when the clinician cancels. You can handle that in two ways. Option 1: Pass props on FormFilling Use this for logic tied to one session. Props mirror client.start() callbacks: Option 2: Listen with client.on() Use this for handlers that stay active across many sessions, such as logging, analytics, or a shared error handler. Register once when you create the client in useMemo:
React
Common events include form-filling:session-started, form-filling:background-submitted, and form-filling:error. Refer to Callbacks for FormFillingResult shape and Events for every event and payload.

Starting another session

When the clinician opens Form filling again, mount FormFilling again (for example set isFormOpen back to true). You do not need a new FormFillingClient. Mount only one FormFilling at a time per client.

useFormFilling hook

Inside FormFillingProvider, use useFormFilling() to read session state and errors in sibling components:
React

Complete code example

Below is a full page example: sign-in, client setup in useMemo, provider wiring, and a button that opens Form filling.
React
Your integration works when the Form filling UI appears, the microphone is active, and onSubmit returns structured_data.

Best practices

  • Reuse one client in useMemo. Do not create FormFillingClient on every render.
  • Mount one FormFilling at a time per client.
  • Pass onSubmit. It is required. Map structured_data.generated_values to your EHR or backend.
  • Pass correlation_id. Use your encounter ID so callbacks and webhooks match the correct record.
  • Use onBackgroundSubmit when results arrive for a session the clinician has already replaced or reopened.
  • Register a partner webhook for production saves on your server, not browser onSubmit alone.
  • Style .suki-form-filling with height before the UI mounts. Zero height is the most common cause of a blank UI.
  • Use template IDs from Suki support. The SDK validates IDs when FormFilling mounts and drops unsupported values.

Troubleshooting

Set CSS height on .suki-form-filling. Add CSP frame-src for https://sdk.suki.ai (production) or https://sdk.suki-stage.com (staging). Refer to Configuration and Prerequisites.
Do not create FormFillingClient on every render. Keep one client in useMemo and pass the same instance to FormFillingProvider.
Mount only one FormFilling at a time per client. Unmount the previous session before starting another.
No forms after resolve, invalid XOR entries, duplicate IDs, or no matching static IDs with no valid dynamic entries. Prefer forms. Refer to Error handling and Dynamic Form filling.
The iframe did not complete the ready handshake within 10 seconds. Check network, ad blockers, and CSP. Confirm the page uses HTTPS.
Auth failed or the wrong environment (staging vs production) while loading the template list. Retry and confirm partnerId, partnerToken, and environment.
Microphone permission denied, session start/submit failed, or form generation failed. Read err.message, show a retry option, and confirm network access.
Sign-in failed before the hosted UI loads. Verify partnerId and partnerToken for your environment. Refer to Authentication.
The clinician closed the processing screen early, or the tab closed before processing finished. Register a partner webhook for server-side delivery.
Pass your encounter ID as correlation_id at session start so callbacks and webhooks match the correct record.
Handle onBackgroundSubmit on FormFilling or listen for form-filling:background-submitted on the client.
Wire onError on the client, useFormFilling() error, or client.on("form-filling:error", ...):
React
Refer to Error handling for the full error code table.

Next steps

Basic usage example - A fuller sample with useFormFilling. Session workflow - Single-form vs multi-form behavior. Configuration - All FormFilling props. Javascript integration - Plain JavaScript.
Last modified on October 16, 2026