> ## 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.

# State and History Adapter Methods in blökkli Reference

> Reference for blökkli state adapter methods: getLastChanged, setHistoryIndex, revertAllChanges, publish, takeOwnership, and changeLanguage.

These adapter methods control the editor's state management features — history tracking, undo/redo, diffing against published content, and the publish workflow. Each method is optional: implement the ones that match your backend's capabilities and blökkli activates the corresponding editor features automatically.

<Note>
  History and undo/redo require your backend to support versioned state storage.
  If your backend is append-only, you can still implement `publish()` and
  `revertAllChanges()` independently.
</Note>

***

## `getLastChanged()`

Enables the **history panel** and **diff view**. blökkli calls this periodically to detect whether the content has changed since the editor was last loaded — for example, if another user made edits in a parallel session.

Return a timestamp string, an integer version counter, or any other value that changes when the content changes. blökkli compares the returned value against the previously stored value using strict equality.

**Signature**

```typescript theme={null}
async getLastChanged(): Promise<string>
```

**Example**

```typescript theme={null}
async getLastChanged(): Promise<string> {
  const data = await $fetch(
    `/api/content/${ctx.state.value.currentEntityUuid}/last-changed`
  )
  return data.timestamp
}
```

<Tip>
  Use an ISO 8601 timestamp (e.g., `"2024-06-15T12:34:56Z"`) for easy
  debugging. A monotonically increasing integer version number also works and
  is cheaper to compare.
</Tip>

***

## `setHistoryIndex({ index })`

Enables **undo and redo**. blökkli maintains a local history index and calls this method when the user triggers an undo (`Ctrl/Cmd+Z`) or redo (`Ctrl/Cmd+Shift+Z`) action. Your backend should restore the content to the state at the given index.

**Signature**

```typescript theme={null}
async setHistoryIndex({ index }: { index: number }): Promise<void>
```

<ParamField body="index" type="number" required>
  The history index to restore. `0` is the oldest recorded state; higher values
  are more recent. blökkli tracks the valid range and only calls this method
  with indices within bounds.
</ParamField>

**Example**

```typescript theme={null}
async setHistoryIndex({ index }: { index: number }): Promise<void> {
  await $fetch(
    `/api/content/${ctx.state.value.currentEntityUuid}/history`,
    {
      method: 'POST',
      body: { index },
    }
  )
}
```

<Warning>
  After `setHistoryIndex()` resolves, blökkli reloads editor state by calling
  `loadState()` and `mapState()`. Ensure your backend has fully committed the
  history restoration before the method resolves.
</Warning>

***

## `revertAllChanges()`

Enables the **Revert** button. Called when the user confirms they want to discard all unpublished changes and return to the last published state. Your backend should delete or discard all draft/pending revisions.

**Signature**

```typescript theme={null}
async revertAllChanges(): Promise<void>
```

**Example**

```typescript theme={null}
async revertAllChanges(): Promise<void> {
  await $fetch(
    `/api/content/${ctx.state.value.currentEntityUuid}/revert`,
    { method: 'POST' }
  )
}
```

<Warning>
  This action is destructive — all unpublished changes are permanently
  discarded. Consider showing a confirmation dialog in your UI before the user
  reaches this adapter call. blökkli shows its own confirmation prompt, but
  your backend should also treat this as an irreversible operation.
</Warning>

***

## `publish()`

Enables the **Publish** button in the editor toolbar. Called when the user clicks Publish and confirms the action. Your backend should persist the current draft state as the active published version.

**Signature**

```typescript theme={null}
async publish(): Promise<void>
```

**Example**

```typescript theme={null}
async publish(): Promise<void> {
  await $fetch(
    `/api/content/${ctx.state.value.currentEntityUuid}/publish`,
    { method: 'POST' }
  )
}
```

<Tip>
  After publishing, you may want to trigger a cache purge or revalidation for
  the affected page. Do this inside `publish()` after the publish request
  resolves, or handle it server-side in your API endpoint.
</Tip>

***

## `takeOwnership()`

Enables the **Ownership** feature. Some content management systems lock an entity to the user who opened it for editing. When another user attempts to edit the same entity, blökkli shows an "in use" warning. Implementing `takeOwnership()` lets the second user forcibly take over the editing session.

**Signature**

```typescript theme={null}
async takeOwnership(): Promise<void>
```

**Example**

```typescript theme={null}
async takeOwnership(): Promise<void> {
  await $fetch(
    `/api/content/${ctx.state.value.currentEntityUuid}/ownership`,
    { method: 'POST' }
  )
}
```

<Note>
  If your backend does not implement entity locking, you do not need this
  method. blökkli only shows the ownership UI when `takeOwnership()` is present
  in the adapter.
</Note>

***

## `changeLanguage({ langcode })`

Enables the **Translations** feature. Called when the user switches the active editing language in the language selector. Navigate to the correct URL or update the query string so the editor reloads with the selected language's content.

**Signature**

```typescript theme={null}
async changeLanguage({ langcode }: { langcode: string }): Promise<void>
```

<ParamField body="langcode" type="string" required>
  The BCP 47 language code of the target language (e.g., `'de'`, `'fr'`,
  `'nl'`). Matches the codes you provide in the `language` prop on
  `<BlokkliProvider>`.
</ParamField>

**Example**

```typescript theme={null}
async changeLanguage({ langcode }: { langcode: string }): Promise<void> {
  await navigateTo({ query: { lang: langcode } })
}
```

<Tip>
  After navigation, blökkli re-initialises the editor for the new language and
  calls `loadState()` again. Ensure your `loadState()` implementation reads the
  current language from the URL or from `ctx.state.value` so it fetches the
  correct translation.
</Tip>
