---
title: "Integrate snapshots"
description: "Editor History for manual and automatic versioning of your documents. Learn how to set up and use it here in the Docs!"
canonical_url: "https://tiptap.dev/docs/collaboration/documents/snapshot"
---

# Integrate snapshots

Editor History for manual and automatic versioning of your documents. Learn how to set up and use it here in the Docs!

Document history records every change to your content so you can roll back mistakes, audit edits, or branch a new draft from any point.

This page walks you through installation, configuration, and common tasks for the **History** extension.

- **1. Activate trial or subscribe**

  Start a free [trial in your Account](https://cloud.tiptap.dev/v2/billing) or subscribe to a [Tiptap plan](https://cloud.tiptap.dev/v2/billing).
- **2. Start Document server**

  [Add an Environment](https://cloud.tiptap.dev/v2/configuration/document-server) in your dashboard and configure your [Document server](https://cloud.tiptap.dev/v2/configuration/document-server).
- **3. Install from private registry**

  To install this extension, authenticate to Tiptap’s private npm registry by following the [setup guide](https://tiptap.dev/docs/guides/pro-extensions.md).

> **Public Demo:**
>
> The editor content is shared across all demo visitors.

> **Interactive demo:** [Snapshot](https://embed-pro.tiptap.dev/preview/Extensions/Snapshot)

## Access the Pro registry

The Version History extension is published in Tiptap’s private npm registry. Integrate the extension by following the [private registry guide](https://tiptap.dev/docs/guides/pro-extensions.md). If you already authenticated your Tiptap account you can go straight to [#Install](#install).

## Install

```bash

npm install @tiptap-pro/extension-snapshot @hocuspocus/transformer

```

**Note**:
The `@hocuspocus/transformer` package is required for transforming Y.js binary into Tiptap JSON. It also requires Y.js installed for collaboration.
If you don't have it installed, run `npm install yjs` in your project. This should happen automatically if you use NPM (as it automatically resolves peer dependencies).

## Settings

| Setting  | Type                   | Default    |
| -------- | ---------------------- | ---------- |
| provider | `TiptapCollabProvider` | `null`     |
| onUpdate | `function`             | `() => {}` |

## Autoversioning

The autoversioning feature automatically creates new versions of your document at regular intervals. This ensures that you have a comprehensive change history without manual intervention.

You can enable this feature using the `enableAutoVersioning` command (default: disabled).

When you enable autoversioning, Tiptap creates new versions at regular intervals (30 seconds by default, only if the document has changed). This can create many versions, so you may want to increase the interval.
To customize the interval, you can do the following:

```typescript
// Set the interval (in seconds) between autoversions
provider.setAutoVersioningInterval(900)
provider.enableAutoVersioning()
provider.disableAutoVersioning()
```

## Revert to a version

When you revert to a previous version:

1. If there are unsaved changes, Tiptap automatically creates a version to preserve those changes.
2. Tiptap creates a new version at the top of the history with the content from the version you select.
3. All users can continue working from this new version.

Note that reverting only affects the `default` fragment in the ydoc. When you revert the Tiptap content, the comments don't change (unless you specify a different `field` in the TiptapCollabProvider).

You can integrate the [compare snapshots](https://tiptap.dev/docs/collaboration/documents/snapshot-compare.md) extension to highlight differences between versions, ensuring you choose the right version to restore.

## Storage

| Key               | Type                   | Description                                                                                                                                                                                                                                                        |
| ----------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| currentVersion    | `number`               | The current version.                                                                                                                                                                                                                                               |
| lastSaved         | `Date`                 | The last saved timestamp                                                                                                                                                                                                                                           |
| latestVersion     | `number`               | The latest version.                                                                                                                                                                                                                                                |
| provider          | `TiptapCollabProvider` | The Collaboration provider instance                                                                                                                                                                                                                                |
| status            | `string`               | The status of the provider - can be `connecting`, `connected` or `disconnected`                                                                                                                                                                                    |
| synced            | `boolean`              | Is the version history synced with the server                                                                                                                                                                                                                      |
| versioningEnabled | `boolean`              | Is versioning enabled                                                                                                                                                                                                                                              |
| versions          | `array<Version>`       | The array of versions that are stored in the history. Each version has `version` (number), `date` (number), `name` (optional string), and `meta` (optional object). See [automatic version metadata](#automatic-version-metadata) for details on the `meta` field. |

## Commands

| Command           | Description                                                                       |
| ----------------- | --------------------------------------------------------------------------------- |
| saveVersion       | Creates a new version with an optional name, force flag, and metadata             |
| fetchVersions     | Fetches the list of versions from the server and updates the storage              |
| enableVersioning  | Enables autoversioning for this document                                          |
| disableVersioning | Disables autoversioning for this document                                         |
| revertToVersion   | Revert to a specific version, can create a new revert version with optional title |

## Examples

### Basic setup

```js
const provider = new TiptapCollabProvider({
  // ...
})

const editor = new Editor({
  // ...
  extensions: [
    // ...
    Snapshot.configure({
      provider,
    }),
  ],
})
```

### Store version updates

In this example we retrieve the data of a version update and save it into a variable

```js
let currentVersion = 0
let latestVersion = 0
let autoversioningEnabled = false
let versions = []

const provider = new TiptapCollabProvider({
  // ...
})

const editor = new Editor({
  // ...
  extensions: [
    // ...
    Snapshot.configure({
      provider,
      onUpdate(payload) {
        currentVersion = payload.currentVersion
        latestVersion = payload.version
        versions = payload.versions
        autoversioningEnabled = payload.versioningEnabled
      },
    }),
  ],
})
```

### Access version data directly from storage

```js
const provider = new TiptapCollabProvider({
  // ...
})

const editor = new Editor({
  // ...
  extensions: [
    // ...
    Snapshot.configure({
      provider,
    }),
  ],
})

const latestVersion = editor.storage.snapshot.latestVersion
const currentVersion = editor.storage.snapshot.currentVersion
const versions = editor.storage.snapshot.versions
const autoversioningEnabled = editor.storage.snapshot.versioningEnabled
```

### Create a new version manually

```js
editor.commands.saveVersion('My new custom version')
```

### Create a version with metadata

You can attach arbitrary metadata to a version. This is useful for storing additional context like the author, tags, or any custom data.

```js
editor.commands.saveVersion('Release v1.0', false, {
  author: 'Jane Doe',
  tags: ['release', 'stable'],
})
```

The `saveVersion` command accepts three parameters:

| Parameter | Type                      | Default     | Description                                         |
| --------- | ------------------------- | ----------- | --------------------------------------------------- |
| name      | `string`                  | `undefined` | An optional name for the version                    |
| force     | `boolean`                 | `false`     | Create the version even if no changes were detected |
| meta      | `Record<string, unknown>` | `undefined` | Arbitrary metadata to attach to the version         |

### Automatic version metadata

Every version automatically includes a `__tiptap` key inside the `meta` object. This metadata is added by the server and provides context about how the version was created and who contributed to it.

A version's `meta` field looks like this:

```json
{
  "__tiptap": {
    "trigger": "websocket",
    "changesBy": ["#user1"],
    "triggeredBy": "user1"
  },
  "wordCount": 81624434
}
```

The `__tiptap` object contains the following fields:

| Field       | Type       | Description                                                                                                                                                                                                                                                |
| ----------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| trigger     | `string`   | How the version was created. Possible values: `"websocket"` (via the editor/provider), `"api"` (via the REST API), `"autoVersioning"` (created automatically by the autoversioning feature), or `"revert"` (created when reverting to a previous version). |
| changesBy   | `string[]` | A list of user identifiers who made changes included in this version.                                                                                                                                                                                      |
| triggeredBy | `string`   | The user identifier of the person who triggered the version creation.                                                                                                                                                                                      |

Any custom metadata you pass to `saveVersion` or the REST API is stored alongside the `__tiptap` key at the top level of `meta`. The `__tiptap` key is reserved and cannot be overwritten by custom metadata.

### Fetch versions from the server

You can manually refresh the list of versions from the server using the `fetchVersions` command. This updates the extension storage with the latest version data.

```js
editor.commands.fetchVersions()
```

### Enable autoversioning on document

```js
editor.commands.enableVersioning()
```

### Disable autoversioning on document

```js
editor.commands.disableVersioning()
```

### Revert with version ID

```js
editor.commands.revertToVersion(4)
```

### Revert with version ID with custom name

In this example, the editor command helps you go back to version 4. When you use this command, it takes you back to how things were in version 4, and it also saves this old version as a new version called 'Revert to version'. This way, you can continue working from version 4, but it's now saved as the latest version.

```js
editor.commands.revertToVersion(4, 'Revert to version')
```

### Revert, name, and back up

In this example, when you revert to version 4 of your document, the editor automatically creates two new versions. The first new version captures and saves your document’s state just before reverting, serving as a backup. The second new version restores the document to version 4, allowing you to continue from here as your new starting point.

```js
editor.commands.revertToVersion(4, 'Revert to version', 'Unversioned changes before revert')
```

### Using provider-level version methods

The `TiptapCollabProvider` exposes methods for working with versions directly, without the Snapshot extension.

#### List versions

Fetch the full list of versions from the server:

```js
const versions = await provider.listVersions()
// versions: Array<{ version: number, date: number, name?: string, meta?: Record<string, unknown> }>
```

#### Get cached versions

Get the locally cached list of versions (no server request):

```js
const versions = provider.getVersions()
```

#### Watch for version changes

Subscribe to version list updates using callbacks:

```js
const onVersionsChange = (versions) => {
  console.log('Versions updated:', versions)
}

// Start watching
provider.watchVersions(onVersionsChange)

// Stop watching
provider.unwatchVersions(onVersionsChange)
```

#### Create a version with metadata

```js
provider.createVersion('My version', false, {
  author: 'Jane Doe',
  tags: ['draft'],
})
```

### Implementing version previews for your editor

The examples above directly modify the document and do not provide local-only previews of the version. Therefore, you must create your own frontend solution for this requirement. You can use the `previewVersion` method on the `TiptapCollabProvider` to request a specific version from the server.

Start by attaching a listener to the provider:

```js
// Import the getPreviewContentFromVersionPayload helper function (refer to details below)
import { watchPreviewContent } from '@tiptap-pro/extension-snapshot'

// Configure the provider
const provider = new TiptapCollabProvider({ ... })

// Use the watchPreviewContent util function to watch for content changes on the provider
const unbindWatchContent = watchPreviewContent(provider, content => {
  // set your editors content
  editor.commands.setContent(content)
})
```

If you want to unbind the watcher, you can call the returned `unbindWatchContent` function like this:

```js
const unbindWatchContent = watchPreviewContent(provider, (content) => {
  // set your editors content
  editor.commands.setContent(content)
})

// unwatch
unbindWatchContent()
```

Following this setup, you can trigger `version.preview` requests like so:

```js
// Request a specific version preview from the server
provider.previewVersion(1)

// You can link this to button clicks or other UI elements to trigger the request.
```

To go beyond previews and compare different versions visually, the [compare snapshots](https://tiptap.dev/docs/collaboration/documents/snapshot-compare.md) extension provides an easy way to see the changes between any two versions within the editor.

## Utility functions

### getPreviewContentFromVersionPayload

This function turns the payload from the Collaboration provider into Tiptap JSON content.

| Argument | Description                                          |
| -------- | ---------------------------------------------------- |
| payload  | The Hocuspocus payload for the version preview event |
| field    | The field you want to parse. Default: `default`      |

```js
const myContent = getPreviewContentFromVersionPayload(payload, 'default')
```

### watchPreviewContent

This function sets up a watcher on your provider that watches the necessary events to react to version content changes. It also returns a new function that you can use to unwatch those events.

| Argument | Description                                                                   |
| -------- | ----------------------------------------------------------------------------- |
| provider | The Collaboration provider                                                    |
| callback | The callback function that is called, the argument is the Tiptap JSON content |
| field    | The watched field - defaults to `default`                                     |

```js
const unwatchContent = watchPreviewContent(provider, editor.commands.setContent, 'default')

// unwatch the version preview content
unwatchContent()
```

## Possible provider payloads

Here is a list of payloads that can be sent or received from the provider:

### Outgoing

#### `document.revert`

Request a document revert to a given version with optional title settings.

```js
provider.revertToVersion(1, {
  currentVersionName: 'Before reverting to version 1',
  newVersionName: 'Revert to version 1',
})
```

#### `version.create`

Creates a new version with an optional name and metadata.

```js
provider.createVersion('My custom version', false, { author: 'Jane Doe' })
```

#### `versions.list`

Requests the full list of versions from the server.

```js
const versions = await provider.listVersions()
```

### Incoming

#### `version.created`

This stateless message includes information about newly created versions, including any metadata that was attached.

```js
provider.on('stateless', (data) => {
  const payload = JSON.parse(data.payload)

  if (payload.event === 'version.created') {
    const latestVersion = payload.version
    const name = payload.name // optional version name
    const date = payload.date // creation timestamp
    const meta = payload.meta // optional metadata object
  }
})
```

#### `versions.list`

The `listVersions` method returns the full list of versions. Each version includes `version`, `date`, and optional `name` and `meta` fields.

```js
const versions = await provider.listVersions()
// versions is an array of { version: number, date: number, name?: string, meta?: object }
```

#### `document.reverted`

This stateless message includes information about a document revert.

```js
provider.on('stateless', (data) => {
  const payload = JSON.parse(data.payload)

  if (payload.event === 'document.reverted') {
    const currentVersion = payload.version
  }
})
```
