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

# Execute voice commands

> Turn spoken command phrases into real editor and application actions

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/d6WKOaS9_Ts?start=346&end=402" title="Execute Voice Commands — walkthrough" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowFullScreen />

<Info>
  **Follow along with the runnable example.** This guide walks through the [Dictation commands example](https://github.com/corticph/corti-examples/tree/main/sdk/typescript/applets/src/applets/dictation-commands) in `corti-examples` — bootstrap your build from it or use it as reference.
</Info>

Commands let users drive your application by voice — delete a segment, insert a template, jump to a field, apply formatting. You declare command **phrases** in the dictation configuration; when the server recognizes one, it emits a `command` event (separate from `transcript`), and your client turns it into a real action.

<Note>
  For the command **configuration schema** (phrases, variables) see [Commands](/stt/commands), and for guidance on designing reliable command phrases see [Commands Tips and Examples](/stt/best-practices-commands). This page focuses on wiring recognized commands to real editor actions.
</Note>

***

## The command loop

<Steps titleSize="h3">
  <Step title="Declare commands">
    Add a `commands` array to your `dictationConfig`. Each command has an `id`, one or more `phrases`, and optional `variables`.
  </Step>

  <Step title="Receive the event">
    On a match, the Web Component emits a `command` event carrying the command `id` and any recognized `variables`.
  </Step>

  <Step title="Dispatch an action">
    Look up the command `id` in a registry and run its handler against your editor.
  </Step>
</Steps>

***

## Declare commands

Phrases can be fixed, or include `{variable}` placeholders. A variable is either an `enum` (a fixed value list) or a `wildcard` (open-ended spoken text). Add a `commands` array to your `dictationConfig` — each entry needs an `id`, one or more `phrases`, and optional `variables`. See the [commands example](https://github.com/corticph/corti-examples/tree/main/sdk/typescript/applets/src/applets/dictation-commands) in `corti-examples` for the full configuration.

<Tip>
  Give every command a unique `id` and non-overlapping `phrases`, and lead with an action verb (`"go to..."`, `"insert..."`). See [Commands Tips and Examples](/stt/best-practices-commands) for the full checklist.
</Tip>

***

## Handle the command event

Listen for the `command` event alongside `transcript`. The event data carries the matched `id` and a `variables` map keyed by your variable `key`s — pass both to your dispatch function.

***

## Dispatch to editor actions

Keep commands **data-driven**: map each command `id` to a handler in a registry, and have every handler act through the same [`EditorAdapter`](/stt/guides/dictation-text-insertion#write-insertion-logic-once-with-an-adapter) used for text insertion — so the identical command logic works against a `<textarea>`, a `contenteditable`, or a native control.

```ts title="JavaScript" theme={null}
type CommandHandler = (editor: EditorAdapter, variables: Record<string, string>) => void;

const registry: Record<string, CommandHandler> = {
  // Delete the most recently dictated segment (tracked in `history`).
  delete_that: (editor) => {
    const last = history.at(-1);
    if (last) editor.replaceRange(last.start, last.end, "");
  },
  // Insert a named template chosen by an enum variable.
  insert_template: (editor, vars) => {
    const template = TEMPLATES[vars.template];
    if (!template) return;
    const { start, end } = editor.getSelection();
    editor.replaceRange(start, end, template);
  },
  // Select free text spoken via a wildcard variable, so the next dictation replaces it.
  select_text: (editor, vars) => {
    const i = editor.getText().toLowerCase().lastIndexOf(vars.text.toLowerCase());
    if (i >= 0) editor.setSelection(i, i + vars.text.length);
  },
};

function dispatch(id: string, variables: Record<string, string>) {
  registry[id]?.(adapter, variables);
}
```

<Note>
  Segment-relative commands like `delete that` need the range of each committed dictation segment. Track those ranges as you insert (see [Text Insertion](/stt/guides/dictation-text-insertion)) and keep them valid as the user types — the example does this with an offset map.
</Note>

<Tip>
  For a user-manageable command set, represent each command's behavior as data — e.g. `insert_text` (fixed text), `keypress` (a keystroke sequence), or a small `script` — rather than a hard-coded function. The example implements exactly these action kinds so users can create and edit their own commands.
</Tip>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Commands" icon="terminal" href="/stt/commands">
    The full command configuration schema: phrases and variables.
  </Card>

  <Card title="Commands Tips and Examples" icon="lightbulb" href="/stt/best-practices-commands">
    Designing reliable command phrases and handling detected commands.
  </Card>

  <Card title="App Control" icon="wand-magic-sparkles" href="/stt/guides/dictation-app-control">
    Drive your application's UI — tabs, panels, dialogs — by voice.
  </Card>

  <Card title="Example code" icon="github" href="https://github.com/corticph/corti-examples/tree/main/sdk/typescript/applets/src/applets/dictation-commands">
    The complete, runnable Dictation commands example in `corti-examples`.
  </Card>
</CardGroup>

<Note>Please [contact us](mailto:help@corti.ai) for help or questions.</Note>
