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

# Editor

> Mount the editable Qirtaas editor and handle content, autosave, and events.

Mount the editor with `client.mountEditor(el, options)`. `el` is an `Element`
or a CSS selector string. It returns an [`EditorInstance`](#editorinstance) for
imperative control.

```ts theme={null}
const editor = qirtaas.mountEditor("#editor", {
  documentId: "b1f2…",
  locale: "ar",
  theme: "light",
  onReady: () => console.log("ready"),
  onChange: (json) => save(json),
  onSaveStateChange: (state) => setBadge(state),
  onDocumentCreated: (id) => (currentDocId = id),
  onError: (code, detail) => report(code, detail),
  onTokenExpired: () => refreshSession(),
});
```

## EditorMountOptions

<ParamField path="documentId" type="string">
  Existing document id to load. Omit to lazy-create a document on the first
  content change — the new id arrives via `onDocumentCreated`.
</ParamField>

<ParamField path="initialContent" type="Json | null">
  Initial content (TipTap JSON) when not loading from a `documentId` — in-memory
  editing.
</ParamField>

<ParamField path="locale" type="&#x22;en&#x22; | &#x22;ar&#x22;">
  Editor UI and content language/direction.
</ParamField>

<ParamField path="theme" type="&#x22;light&#x22; | &#x22;dark&#x22;">
  Color theme. Can be changed live via `setTheme`.
</ParamField>

<ParamField path="readOnly" type="boolean" default="false">
  Start read-only. Editing can be toggled later via `setEditable()`.
</ParamField>

<ParamField path="autofocus" type="boolean" />

<ParamField path="autosave" type="AutosaveOptions">
  Autosave behavior. See [Types](/sdk/types#autosaveoptions). Set
  `{ enabled: false }` to drive persistence yourself via `save()`.
</ParamField>

### Callbacks

<ParamField path="onReady" type="() => void">
  Fired once the editor is mounted and (if loading) the document is in.
</ParamField>

<ParamField path="onChange" type="(json: Json) => void">
  Fired on every content change with the current TipTap JSON.
</ParamField>

<ParamField path="onSaveStateChange" type="(state: SaveState) => void">
  Fired when autosave transitions between `idle | saving | saved | error`.
</ParamField>

<ParamField path="onDocumentCreated" type="(id: string) => void">
  Fired with the new id when a document is lazy-created.
</ParamField>

<ParamField path="onError" type="(code: ErrorCode, detail?: unknown) => void">
  Fired on recoverable/unrecoverable errors with a stable
  [error code](/sdk/types#errorcode).
</ParamField>

<ParamField path="onTokenExpired" type="() => void">
  Fired when a forced token refresh fails; autosave pauses until recovery.
</ParamField>

<ParamField path="onEvent" type="(name: string, props?) => void">
  Analytics passthrough for editor interaction events.
</ParamField>

## EditorInstance

The object returned by `mountEditor`:

<ResponseField name="getJSON()" type="Json | null">
  Current editor content (TipTap JSON).
</ResponseField>

<ResponseField name="save()" type="Promise<void>">
  Force an immediate save of any pending changes.
</ResponseField>

<ResponseField name="setEditable(editable)" type="void">
  Toggle read-only / editable live.
</ResponseField>

<ResponseField name="setTheme(theme)" type="void">
  Switch theme (`"light" | "dark"`) live.
</ResponseField>

<ResponseField name="destroy()" type="void">
  Tear down the editor and release the shared overlay root. Call this on unmount.
</ResponseField>

## Manual save (autosave off)

```ts theme={null}
const editor = qirtaas.mountEditor("#editor", {
  autosave: { enabled: false },
  onChange: (json) => setDirty(true),
});

// later, e.g. on your own "Save" button:
await editor.save();
```
