---
title: "Types"
description: "TypeScript type definitions for the Tiptap Tracked Changes extension."
canonical_url: "https://tiptap.dev/docs/tracked-changes/api-reference/types"
---

# Types

TypeScript type definitions for the Tiptap Tracked Changes extension.

The extension exports TypeScript types for working with suggestions.

## SuggestionType

Public-facing suggestion type returned by the query API:

```ts
type SuggestionType = 'add' | 'delete' | 'replace' | 'markChange'
```

## SuggestionMarkType

Internal mark-level type stored on suggestion marks. Replace suggestions use separate mark types for their deletion and insertion parts:

```ts
type SuggestionMarkType = 'add' | 'delete' | 'replaceDeletion' | 'replaceInsertion' | 'markChange'
```

## SuggestionMarkChangeOperation

Operation stored in a mark-change suggestion:

```ts
type SuggestionMarkChangeOperation = 'added' | 'removed'
```

## SuggestionMarkChange

Describes one mark mutation stored on a `markChange` suggestion:

```ts
type SuggestionMarkChange = {
  operation: SuggestionMarkChangeOperation
  markName: string
  markAttrs: Record<string, unknown> | null
}
```

## Suggestion

Represents a suggestion found in the document:

```ts
type Suggestion = {
  id: string
  type: SuggestionType
  userId: string
  createdAt: string
  updatedAt: string
  userMetadata: Record<string, unknown> | null
  from: number
  to: number
  text: string
  fullText: string
  // Only present for 'replace' suggestions:
  deletionRange?: { from: number; to: number }
  insertionRange?: { from: number; to: number }
  replacedText?: string
  // Only present for 'markChange' suggestions:
  markChanges?: SuggestionMarkChange[]
  // Only present when the suggestion affects block-level nodes:
  insertedNodes?: JSONContent[]
  deletedNodes?: JSONContent[]
}
```

- `createdAt` — ISO 8601 timestamp of when the suggestion was first created
- `updatedAt` — ISO 8601 timestamp of the most recent edit within the suggestion. Falls back to `createdAt` for legacy data that predates this field.

### `text` vs `fullText`

- `text` — the text authored by this suggestion **alone**, excluding text inserted by nested (stacked) suggestions layered on top of it. For `replace` suggestions, this is the new (inserted) text.
- `fullText` — the complete, continuous text spanned by this suggestion's marks, **including** any text inserted by nested suggestions from other authors. For `replace` suggestions, this is the new (inserted) text.

For the vast majority of suggestions (no stacking) `text === fullText`. They diverge only when another author has **inserted** text via a [nested suggestion](https://tiptap.dev/docs/tracked-changes/usage/advanced-usage.md#nested-and-stacked-suggestions) inside this one.

Note that `text` only drops text that a nested suggestion **inserted**. A nested delete or mark-change does not insert content, so it never reduces the outer author's `text`. For example, if author A inserts `"hello"` and author B deletes `"ll"` inside it, A's `text` is still `"hello"` — B's deletion didn't add any text that belongs to B.

#### Worked example

Author A inserts `"Hello world"`, then author B inserts `"great "` before `"world"` (nested inside A's addition):

| Suggestion      | `text`          | `fullText`            |
| --------------- | --------------- | --------------------- |
| A (add, user-1) | `"Hello world"` | `"Hello great world"` |
| B (add, user-2) | `"great "`      | `"great "`            |

```ts
import { findSuggestions } from '@tiptap-pro/extension-tracked-changes'

const suggestions = findSuggestions(editor)
const outer = suggestions.find(s => s.userId === 'user-1')

outer.text // "Hello world"        → show this in a review sidebar
outer.fullText // "Hello great world"  → use when you need the literal span
```

Default to `text` when displaying "what this person changed" (review panels, comment threads, activity logs). Reach for `fullText` only when you need the exact contiguous text the mark covers in the document.

For `replace` suggestions:

- `text` contains the **new** (inserted) text
- `replacedText` contains the **old** (deleted) text
- `deletionRange` and `insertionRange` give the exact positions of each part
- `from` and `to` cover the full range of both parts

For `markChange` suggestions:

- `text` contains the affected text content
- `markChanges` contains the tracked mark operations, including mark names and attrs

For block-level node suggestions (e.g. inserting or deleting a paragraph or heading):

- `text` always contains the actual text content of the affected node — never a `[nodeName]` placeholder
- `insertedNodes` contains the full JSON representation of each inserted node
- `deletedNodes` contains the full JSON representation of each deleted node

Use `insertedNodes` and `deletedNodes` to inspect node types and attributes when building richer UIs, such as displaying a node type badge alongside the suggestion text.

## SuggestionMarkAttrs

Attributes stored on the suggestion mark:

```ts
type SuggestionMarkAttrs = {
  id: string
  type: SuggestionMarkType
  userId: string
  createdAt: string
  updatedAt: string
  userMetadata: Record<string, unknown> | null
  markChanges?: SuggestionMarkChange[] | null
}
```

## SuggestionChangedEventPayload

Payload for the `trackedChanges:suggestionChanged` event. Fires whenever any content-bearing field of a suggestion changes, including range positions, text, mark changes, or type.

```ts
type SuggestionChangedEventPayload = {
  suggestionId: string
  oldSuggestion: Suggestion
  suggestion: Suggestion
  transaction: Transaction
}
```

- `oldSuggestion` — snapshot of the suggestion before the change
- `suggestion` — the current (updated) suggestion
- `transaction` — the ProseMirror transaction that caused the change

## SuggestionRangeChangedEventPayload

Payload for the `trackedChanges:suggestionRangeChanged` event. Fires only when a suggestion's document positions shift.

```ts
type SuggestionRangeChangedEventPayload = {
  suggestionId: string
  oldRange: { from: number; to: number }
  newRange: { from: number; to: number }
  suggestion: Suggestion
  transaction: Transaction
}
```

## TrackedChangesOptions

Configuration options for the extension:

```ts
type TrackedChangesOptions = {
  enabled: boolean
  userId: string
  userMetadata?: Record<string, unknown> | null
  ignoredTrackingMarks: string[]
  onSuggestionCreate?: (suggestion: Suggestion) => void
  onSuggestionAccept?: (id: string) => void
  onSuggestionReject?: (id: string) => void
}
```

## Type helpers

The extension exports constants and helper functions for working with suggestion types:

```ts
import {
  SUGGESTION_TYPES,
  isAddLikeType,
  isDeleteLikeType,
  isReplaceMarkType,
  markTypeToSuggestionType,
} from '@tiptap-pro/extension-tracked-changes'

// Constants
SUGGESTION_TYPES.ADD              // 'add'
SUGGESTION_TYPES.DELETE           // 'delete'
SUGGESTION_TYPES.REPLACE_DELETION  // 'replaceDeletion'
SUGGESTION_TYPES.REPLACE_INSERTION // 'replaceInsertion'
SUGGESTION_TYPES.MARK_CHANGE      // 'markChange'

// Check if a mark type represents added content (matches 'add' and 'replaceInsertion')
isAddLikeType('add') // true
isAddLikeType('replaceInsertion') // true

// Check if a mark type represents deleted content (matches 'delete' and 'replaceDeletion')
isDeleteLikeType('delete') // true
isDeleteLikeType('replaceDeletion') // true

// Check if a mark type is one of the replace sub-types
isReplaceMarkType('replaceDeletion') // true

// Convert a mark-level type to the public-facing suggestion type
markTypeToSuggestionType('replaceDeletion') // 'replace'
markTypeToSuggestionType('add') // 'add'
```
