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

# Block Mutation Methods in the blökkli Adapter Reference

> Optional adapter methods for block CRUD operations: deleteBlocks, duplicateBlocks, updateOptions, updateFieldValue, and conversion/transform methods.

Beyond the [required methods](/api/adapter-required), implement these adapter methods to enable additional block manipulation features in the editor. Each method is optional — blökkli disables the corresponding editor feature when a method is not provided. You only need to implement the methods that match the capabilities of your backend.

<Note>
  All parameter and return types referenced below are exported from
  `@blokkli/editor`. Import them for full type safety in your adapter.
</Note>

***

<Accordion title="deleteBlocks({ uuids })">
  Enables the **Delete** toolbar action. blökkli calls this when the user selects one or more blocks and triggers the delete action (keyboard shortcut or toolbar button).

  **Signature**

  ```typescript theme={null}
  async deleteBlocks({ uuids }: { uuids: string[] }): Promise<void>
  ```

  <ParamField body="uuids" type="string[]" required>
    Array of UUIDs for the blocks to delete.
  </ParamField>

  **Example**

  ```typescript theme={null}
  async deleteBlocks({ uuids }: { uuids: string[] }): Promise<void> {
    await $fetch('/api/blocks', {
      method: 'DELETE',
      body: { uuids },
    })
  }
  ```

  <Warning>
    Deletion is irreversible unless your backend supports history. If you
    implement `setHistoryIndex()`, blökkli can undo a delete by navigating back
    through history.
  </Warning>
</Accordion>

***

<Accordion title="duplicateBlocks({ uuids })">
  Enables the **Duplicate** toolbar action. Your backend must create copies of the given blocks with new UUIDs and insert them directly after their originals.

  **Signature**

  ```typescript theme={null}
  async duplicateBlocks({ uuids }: { uuids: string[] }): Promise<void>
  ```

  <ParamField body="uuids" type="string[]" required>
    Array of UUIDs for the blocks to duplicate. Preserve the order when
    creating copies.
  </ParamField>

  **Example**

  ```typescript theme={null}
  async duplicateBlocks({ uuids }: { uuids: string[] }): Promise<void> {
    await $fetch('/api/blocks/duplicate', {
      method: 'POST',
      body: { uuids },
    })
  }
  ```

  <Tip>
    After the call resolves, blökkli re-fetches state via `loadState()` and
    `mapState()` to reflect the newly created blocks with their server-assigned
    UUIDs.
  </Tip>
</Accordion>

***

<Accordion title="updateOptions({ uuid, options })">
  Enables the **Options panel** sidebar. blökkli calls this whenever the user changes any option value for a block — text fields, toggles, selects, and so on.

  **Signature**

  ```typescript theme={null}
  async updateOptions(input: UpdateOptionsInput): Promise<void>
  ```

  <ParamField body="uuid" type="string" required>
    UUID of the block whose options are being updated.
  </ParamField>

  <ParamField body="options" type="Record<string, any>" required>
    The full options object for the block, including both changed and unchanged
    values.
  </ParamField>

  **Example**

  ```typescript theme={null}
  async updateOptions({ uuid, options }: UpdateOptionsInput): Promise<void> {
    await $fetch(`/api/blocks/${uuid}/options`, {
      method: 'PATCH',
      body: { options },
    })
  }
  ```
</Accordion>

***

<Accordion title="updateFieldValue({ uuid, fieldName, value })">
  Enables **inline editable fields** — block fields that the user can edit directly on the canvas (for example, a text block's body content). Called each time the user commits a change to an editable field value.

  **Signature**

  ```typescript theme={null}
  async updateFieldValue(input: UpdateFieldValueInput): Promise<void>
  ```

  <ParamField body="uuid" type="string" required>
    UUID of the block containing the field being updated.
  </ParamField>

  <ParamField body="fieldName" type="string" required>
    The name of the field being updated (e.g., `'body'`, `'title'`).
  </ParamField>

  <ParamField body="value" type="any" required>
    The new value for the field. The type depends on the field definition in
    your block component.
  </ParamField>

  **Example**

  ```typescript theme={null}
  async updateFieldValue({
    uuid,
    fieldName,
    value,
  }: UpdateFieldValueInput): Promise<void> {
    await $fetch(`/api/blocks/${uuid}/fields/${fieldName}`, {
      method: 'PATCH',
      body: { value },
    })
  }
  ```
</Accordion>

***

<Accordion title="getConversions({ uuids })">
  Enables the **Convert** block type feature. blökkli calls this when the user opens the conversion menu for a selection of blocks. Return the available conversion targets.

  **Signature**

  ```typescript theme={null}
  async getConversions({ uuids }: { uuids: string[] }): Promise<ConversionItem[]>
  ```

  <ParamField body="uuids" type="string[]" required>
    UUIDs of the selected blocks for which conversion options are requested.
  </ParamField>

  **Example**

  ```typescript theme={null}
  async getConversions({ uuids }: { uuids: string[] }) {
    return $fetch('/api/blocks/conversions', {
      method: 'POST',
      body: { uuids },
    })
  }
  ```
</Accordion>

***

<Accordion title="convertBlocks({ uuids, targetBundle })">
  Performs a block type conversion. blökkli calls this after the user selects a target bundle from the conversion menu returned by `getConversions()`.

  **Signature**

  ```typescript theme={null}
  async convertBlocks(input: ConvertBlocksInput): Promise<void>
  ```

  <ParamField body="uuids" type="string[]" required>
    UUIDs of the blocks to convert.
  </ParamField>

  <ParamField body="targetBundle" type="string" required>
    The bundle identifier to convert the blocks into.
  </ParamField>

  **Example**

  ```typescript theme={null}
  async convertBlocks({
    uuids,
    targetBundle,
  }: ConvertBlocksInput): Promise<void> {
    await $fetch('/api/blocks/convert', {
      method: 'POST',
      body: { uuids, targetBundle },
    })
  }
  ```

  <Note>
    Both `getConversions()` and `convertBlocks()` must be implemented together for
    the conversion feature to activate. Implementing only one has no effect.
  </Note>
</Accordion>

***

<Accordion title="getTransformPlugins()">
  Enables the **Transform** feature. blökkli calls this on editor activation to discover which transform plugins are available. Transform plugins run server-side logic on a block selection — for example, merging text blocks or splitting a block by paragraph.

  **Signature**

  ```typescript theme={null}
  async getTransformPlugins(): Promise<TransformPlugin[]>
  ```

  **Example**

  ```typescript theme={null}
  async getTransformPlugins() {
    return $fetch('/api/transforms')
  }
  ```
</Accordion>

***

<Accordion title="applyTransformPlugin({ pluginId, uuids })">
  Applies a transform plugin to the selected blocks. blökkli calls this after the user selects a plugin from the transform menu.

  **Signature**

  ```typescript theme={null}
  async applyTransformPlugin(input: ApplyTransformInput): Promise<void>
  ```

  <ParamField body="pluginId" type="string" required>
    The identifier of the transform plugin to apply (as returned by
    `getTransformPlugins()`).
  </ParamField>

  <ParamField body="uuids" type="string[]" required>
    UUIDs of the blocks to transform.
  </ParamField>

  **Example**

  ```typescript theme={null}
  async applyTransformPlugin({
    pluginId,
    uuids,
  }: ApplyTransformInput): Promise<void> {
    await $fetch(`/api/transforms/${pluginId}`, {
      method: 'POST',
      body: { uuids },
    })
  }
  ```

  <Note>
    Both `getTransformPlugins()` and `applyTransformPlugin()` must be implemented
    together for the transform feature to activate.
  </Note>
</Accordion>
