> ## Documentation Index
> Fetch the complete documentation index at: https://developer.suki.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Dictation SDK JavaScript Integration

> Integrate `@suki-sdk/dictation` in vanilla JavaScript: install packages, create `SukiAuthManager` and `DictationClient`, and open in-field or scratchpad sessions

This guide shows how to integrate the Suki Dictation SDK into browser-based web applications using the JavaScript package. You'll initialize the `DictationClient`, connect it to your application's input field or editor, and start Dictation sessions from your own code.

Use this approach if you're building with vanilla JavaScript, Vue, Angular, or another non-React framework, or if you need full control over when and where the Dictation interface is displayed.

Let's get started!

## Prerequisites

Before you begin, you must have the following requirements met:

* **Packages:** Install `@suki-sdk/dictation` and `@suki-sdk/core` packages.
* **Partner credentials:** Obtain `partnerId` and `partnerToken` from Suki after [Partner onboarding](/documentation/get-started/partner-onboarding).
* **Browser and layout:** Your app runs in a **browser**, with a real DOM and a Dictation **container** that has height.

Refer to [Prerequisites](/dictation-sdk/prerequisites) guide for more details.

## Install the packages

Add both packages to the same project you load in the browser:

<CodeGroup title="Install the @suki-sdk/dictation and @suki-sdk/core Packages">
  ```shell pnpm theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  pnpm add @suki-sdk/core @suki-sdk/dictation 
  ```

  ```shell npm theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  npm install @suki-sdk/core @suki-sdk/dictation 
  ```

  ```shell yarn theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  yarn add @suki-sdk/core @suki-sdk/dictation 
  ```
</CodeGroup>

<Tip>
  After you install, pull the SDK into your files with **`import`**, the same way as in the examples below. Use whatever approach your project already uses for other npm libraries.
</Tip>

## Step 1: Add container and field HTML

For this example we will assume you are using **`in-field`** mode as your preferred mode.

In **`in-field`** mode you need **two** nodes in the page: a **`div`** (or similar) that you pass as **`rootElement`**, where the Dictation controls show up, and a **textarea** (or input) that **`onSubmit`** will update when the user finishes.

The Dictation layer **matches the size of** **`rootElement`**, so that node should have a **height** you control. Refer to [Wrapper layout](/dictation-sdk/guides/configuration#wrapper-layout) guide for recommended markup and CSS.

```html HTML theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
<div id="dictation-root"></div>
<label for="clinical-notes">Clinical notes</label>
<textarea id="clinical-notes" rows="8"></textarea>
<button type="button" id="start-dictation">Start dictation</button>
```

## Step 2: Create auth manager

Now you need to create the **Auth Manager** for your application. To create the Auth Manager, you must have the `partnerId` and `partnerToken` credentials from Suki.
Refer to [Partner onboarding](/documentation/get-started/partner-onboarding) guide to learn how to get these credentials.

Once you have all the required credentials, create **one** auth manager for the page (or app shell).

**Code example for creating auth manager**

```js JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import { SukiAuthManager } from "@suki-sdk/core";

const authManager = new SukiAuthManager({
  partnerId: "YOUR_PARTNER_ID", // replace with your partner ID - required
  partnerToken: "YOUR_PARTNER_TOKEN", // replace with your partner token - required
  environment: "staging", // optional: "staging" | "production"
  loginOnInitialize: true, // optional: sign in as soon as this runs
  autoRegister: false, // optional: enable provider auto-registration
  providerId: "YOUR_PROVIDER_ID", // optional: provider identifier in your system
  providerName: "YOUR_PROVIDER_NAME", // optional: full provider display name
  providerOrgId: "YOUR_PROVIDER_ORG_ID", // optional: organization identifier for the provider in your system
  providerSpecialty: "YOUR_PROVIDER_SPECIALTY", // optional: clinical specialty
});
```

## Step 3: Create Dictation client

After you have created the auth manager, you can create the **Dictation client** for your application. The Dictation Client is the object that will be used to start the Dictation session.

Create **one** Dictation client and reuse it for every **`show()`** call on that page.

**Code example for creating Dictation client**

```js JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import { DictationClient } from "@suki-sdk/dictation";

const dictationClient = new DictationClient({ authManager });
```

## Step 4: Call show() to start Dictation

Now you can start the Dictation session by calling the **`show()`** method on the Dictation client.

Call **`await dictationClient.show({ ... })`** from a click handler (or similar) when the DOM is ready.
Pass **`mode`**, **`fieldId`**, **`rootElement`**, **`onSubmit`**, and any optional fields you need. Refer to [Configuration](/dictation-sdk/guides/configuration) guide for more details on the available options and how to use them.

**Code example for starting Dictation**

```javascript JavaScript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
async function startDictation() {
  const root = document.getElementById("dictation-root");
  const notes = document.getElementById("clinical-notes");

  if (!root || !notes) {
    console.error("Missing dictation-root or clinical-notes in the DOM");
    return;
  }

  try {
    await dictationClient.show({
      mode: "in-field", // replace with your preferred mode - required
      fieldId: "clinical-notes", // often the same string as the textarea id
      rootElement: root, // replace with the DOM element where the dictation controls will be shown - required
      initialText: notes.value ?? "", // replace with the initial text for the dictation session - optional
      onSubmit: ({ fieldId, text }) => { 
        const el = document.getElementById(fieldId);
        if (el) el.value = text;
      },
      onCancel: ({ fieldId }) => {
        console.log("Dictation cancelled", fieldId);
      },
      onDraft: ({ fieldId, text }) => {
        const el = document.getElementById(fieldId);
        if (el) el.value = text; // optional live preview while dictating
      },
    });
  } catch (err) {
    console.error("Dictation show() failed", err);
  }
}

document.getElementById("start-dictation")?.addEventListener("click", () => {
  void startDictation();
});
```

<Note>
  **`onSubmit`** is required for a good user experience. If you omit it, Dictation often **closes immediately** after the user acts.
</Note>

## Callbacks

Every callback receives the same shape as shown in the code example below:

```javascript JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{ fieldId: string, 
text: string 
}
```

Refer to [Callbacks](/dictation-sdk/guides/callbacks) guide for more details on the available callbacks and how to use them.

## Switching fields

Calling **`show()`** again **replaces** the active session. You do **not** need to call **`hide()`** manually just to move from one field to another:

```js JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
await dictationClient.show({ /* field A options */ });
await dictationClient.show({ /* field B options */ });
```

## Complete code example

Below is a complete code example in JavaScript for in-field mode with a single field.

```js JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import { SukiAuthManager } from "@suki-sdk/core";
import { DictationClient } from "@suki-sdk/dictation";

const authManager = new SukiAuthManager({
  partnerId: "YOUR_PARTNER_ID", // replace with your partner ID - required
  partnerToken: "YOUR_PARTNER_TOKEN", // replace with your partner token - required
  environment: "staging", // optional: "staging" | "production"
  loginOnInitialize: true, // optional: sign in as soon as this runs
  autoRegister: false, // optional: enable provider auto-registration
  providerId: "YOUR_PROVIDER_ID", // optional: provider identifier in your system
  providerName: "YOUR_PROVIDER_NAME", // optional: full provider display name
  providerOrgId: "YOUR_PROVIDER_ORG_ID", // optional: organization identifier for the provider in your system
  providerSpecialty: "YOUR_PROVIDER_SPECIALTY", // optional: clinical specialty
});

const dictationClient = new DictationClient({ authManager });

async function startClinicalNotesDictation() {
  const root = document.getElementById("dictation-root");
  const notes = document.getElementById("clinical-notes");
  if (!root || !notes) return;

  try {
    await dictationClient.show({
      mode: "in-field",
      fieldId: "clinical-notes",
      rootElement: root,
      initialText: notes.value ?? "",
      onSubmit: ({ fieldId, text }) => {
        const el = document.getElementById(fieldId);
        if (el) el.value = text;
      },
      onCancel: ({ fieldId }) => {
        console.log("Cancelled", fieldId);
      },
    });
  } catch (e) {
    console.error(e);
  }
}

document.addEventListener("DOMContentLoaded", () => {
  document
    .getElementById("start-dictation")
    ?.addEventListener("click", () => void startClinicalNotesDictation());
});
```

<Tip>
  This page focuses on **`in-field`** Dictation next to a specific input. If you want a **floating Dictation panel** instead, set **`mode`** to **`"scratchpad"`** and follow [Scratchpad mode](/dictation-sdk/guides/scratchpad-mode) guide.
</Tip>

## Best practices

<Tip>
  * **Reuse one Dictation client.** Build a single **DictationClient** for the page or shell and call it again for each Dictation session. Creating a new client on every click or for every field often resets the hosted UI and feels flaky.

  * **Reuse one auth manager.** Create **SukiAuthManager** once and pass that same instance into the client, the same pattern as in the steps above.

  * **Handle when the user commits.** You must supply a submit handler so the SDK can deliver the final text. Without it, Dictation often closes right after the user tries to finish.

  * **Pick a clear field label.** Each session needs a stable, unique **fieldId** in callbacks. Using the same value as the target input's **id** is a simple way to know which element to update. Refer to [Field IDs](/dictation-sdk/guides/configuration#field-ids-in-practice) guide for more details.

  * **Open Dictation only when the host is ready.** The DOM node you use as the Dictation host should exist and have real height before you open. Otherwise the Dictation area can look blank. Refer to [Error handling](/dictation-sdk/guides/error-handling) and [In-field mode](/dictation-sdk/guides/in-field-mode) guides for more details.

  * **Catch failures when opening Dictation.** Wrap the open call so auth or setup errors show up in your logs instead of disappearing.

  * **Move to another field by opening again.** A new open call replaces the active session. You usually do not need a separate hide step when you are only switching which field is dictating.
</Tip>

## Next steps

Refer to the following guides for more information.

<Icon icon="file-lines" iconType="solid" /> [Configuration](/dictation-sdk/guides/configuration) to learn about the available options and how to use them.

<Icon icon="file-lines" iconType="solid" /> [React integration](/dictation-sdk/react-integration/react) to learn how to integrate the Dictation SDK with React.
