---
title: "Suggested Edits Plugin"
description: "Suggested Edits keeps track of changes and review edits made by multiple authors in a document."
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/suggestededits/"
md_url: "https://www.tiny.cloud/docs/tinymce/latest/suggestededits/index.md"
version: "latest"
last_updated: "2026-07-02T01:24:13Z"
tokens: 6404
---
# Suggested Edits Plugin

> **Note:** This plugin is only available as a **paid add-on** to [a TinyMCE subscription](/pricing/).
The Suggested Edits plugin allows multiple users to collaborate on a document. The review window shows which user suggested which edits, whether they added, removed, modified, or replaced any content, and allows users to provide feedback on those suggestions or give a final review by accepting or rejecting them.

## Interactive example

**Example**

```js
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

const tinymceElement = document.querySelector('textarea#suggestededits');
const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits',
  height: 500,
  plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
  toolbar: 'undo redo | suggestededits suggestededits-tracking | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
  
  suggestededits_model: model,
  suggestededits_access: 'full',
  suggestededits_content: 'html',
  view_show: 'suggestededits',
  user_id: 'kai-nakamura',
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`${API_URL}/${userId}`)
        .then((response) => response.json())
        .catch(() => ({ id: userId }))))
});
```

> **Note:** This feature is only supported when TinyMCE is run in *classic* mode. It is not supported in *inline* mode. For more information on the differences between the editing modes, see [Classic editing mode](../use-tinymce-classic/).

> **Note:** For information on bundling this plugin with module bundlers, see [Bundling TinyMCE - Overview](../bundling-guide/).

## How it works

The Suggested Edits plugin keeps track of every edit made to the document by the current user and stores this metadata in an internal model of the document. These suggestions can then be reviewed in the Review Edits view, where each edit is highlighted in the document, and where users can accept, reject, or provide feedback. The Review Edits view is accessible via either the `suggestededits` toolbar button or menu button within the `View` menu.

## The model

The Suggested Edits model is a JSON object representing the document along with all unreviewed edits and feedback. The model must be kept in sync with the editor content and loaded into the editor at the same time as the content.

The structure of the model is not documented and should not be relied upon. Models saved by earlier versions of the plugin continue to load and are upgraded automatically.

The model can be retrieved from the plugin using the [`getModel`](#get_model) API, saved externally alongside the document, and loaded into the editor with the [`suggestededits_model`](#suggestededits_model) option. This ensures that the document and the model are in sync and every user’s contributions are tracked correctly. If the model and content are out of sync when the editor loads, the difference between them will be included in the next edit by the current user. If a model is not provided in the editor configuration or is set to `undefined`, the plugin will generate a new model from the initial content.

Alternatively the [`suggestededits_content`](#suggestededits_content) option allows the model to generate the editor content, in which case the two do not need to be kept in sync.

## Reviewing edits

The Review Edits view can be used to view and reviewing edits made by multiple authors. The available actions in this view depends on the [`suggestededits_access` option](#suggestededits_access).

### Header

The view contains a few controls to manage the review process:

- Show edits: Toggles whether suggested edits are shown. When hidden, the view shows what the document will look like if the review is completed.
- Complete review: Ends the review, applying resolved suggestions to the document. Unresolved suggestions remain in the document for future review.
- Cancel: Ignores any resolved suggestions and makes no change to the document. Feedback given on suggestions will be retained.

### Document

The current editor document is displayed in a sandboxed iframe, with each suggested edit highlighted as they appear in the document. The following color coding is used to indicate the type of change:

- Green: Added content.
- Blue: Modified attributes or formatting (e.g. bold, italic, etc.).
- Red: Removed content.

Replaced content is represented as both added and removed content, and indicates that some content was removed and replaced with new content in a single edit. When a suggestion is selected, whether in the document or in the sidebar, the corresponding highlighted suggestion in the document will be outlined in blue and scrolled into view.

### Sidebar

Each suggested edit is listed as a card in the sidebar and color coded by the type of change. Each card shows a contextual description of the content, along with the user who made the suggestion, when the edit was made, and any feedback provided on that suggestion.

Edits made with the [TinyMCE AI](../tinymceai/) plugin are recorded as AI-assisted. An AI badge appears on their cards by default. Set [`suggestededits_ai_attribution`](#suggestededits_ai_attribution) to `false` to hide the badge.

When selected, a suggestion can be handled in the following ways:

- Accept: Resolves the suggestion, applying the edit to the document when the review is completed.
- Reject: Resolves the suggestion, turning back the edit to the original state.
- Revert: Reverts the current "Accept" or "Reject" resolution on the suggestion.
- Provide feedback: Opens a text area for users to provide feedback on the suggestion.

Feedback is shown in chronological order beneath the card details when the card is selected. Feedback allows users to discuss suggestions before resolving them. The feedback author can edit or delete their own feedback, with the appropriate permissions in the [`suggestededits_access`](#suggestededits_access) option.

At the top of the sidebar there is a dropdown menu to apply review actions in bulk to all suggested edits:

- Accept all.
- Reject all.
- Revert all.

### Finishing a review

When completing a review, resolved suggestions will be applied to the document and will no longer be tracked in the model as a suggestion. Feedback on resolved suggestions is discarded. Any "accepted" edits will remain in the document, and any "rejected" edits will be reverted to the state before the suggestion was made.

Review actions will apply the following to the document:

When added content is:

- Accepted: The content will remain in the document.
- Rejected: The content will be removed from the document.

When modified content is:

- Accepted: The content will retain the current formats and attributes.
- Rejected: The content will revert to modified formats and attributes to match the content state before the edit was made.

When removed content is:

- Accepted: The content will be removed from the document.
- Rejected: The removed content will be restored to the document.

If a review is canceled, no resolved suggestions will be applied to the document. All suggestions, including any feedback provided during that review session, will remain stored in the model.

## Initial setup

To setup the Suggested Edits plugin in the editor:

- add `suggestededits` to the `plugins` option in the editor configuration;
- add `suggestededits` to the `toolbar` option in the editor configuration;

For example:

```js
tinymce.init({
  selector: 'textarea#suggestededits',  // change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
});
```
This configuration adds Suggested Edits to the editor toolbar, enabling access to the plugin features. To fully utilize the plugin, additional configuration options must be provided.

## Options

The following configuration options affect the behavior of the Suggested Edits plugin.

### `suggestededits_model`

The `suggestededits_model` option loads an existing model into the Suggested Edits plugin. This model contains all current suggested edits and is used to maintain continuity across sessions. If a model is not provided, the plugin generates a new model from the initial editor content.

**Type:** `Object`

Example: using `suggestededits_model`
```js
const tinymceElement = document.querySelector('textarea#suggestededits');
const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits',  // Change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  suggestededits_model: model // Load the saved model into the editor
});
```

### `suggestededits_content`

The `suggestededits_content` option controls whether the content is loaded from the editor or the `suggestededits_model` model, allowing you to define the source of truth for the document. In either case, if a model is not provided, the plugin will generate a new model from the initial editor content.

When set to:

- `'html'`: the editor loads content normally, and the plugin synchronises the model with the content. This simplifies the configuration of Suggested Edits in an existing integration, by attaching the Suggested Edits model as an additional field alongside the editor content.
- `'model'`: the editor uses the `suggestededits_model` option to generate the initial content, ignoring any pre-existing content in the editor. With this configuration, you only need to store and provide the model, simplifying the integration of the Suggested Edits plugin.

> **Note:** You are responsible for saving the model and providing it on the next load using the `suggestededits_model` option.
**Type:** `String`

**Possible Values**: `'html'`, `'model'`

**Default value:** `'html'`

Example: using `suggestededits_content`
```js
const tinymceElement = document.querySelector('textarea#suggestededits');
const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits',  // Change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  suggestededits_model: model, // Load the saved model into the editor
  suggestededits_content: 'model' // Set to 'model' if you want to load the initial content from the `suggestededits_model` option
});
```

### `suggestededits_access`

The `suggestededits_access` option determines the level of access a user has to the Suggested Edits view. This setting is crucial for controlling who can accept or reject suggestions, add feedback, or view suggestions in read-only mode. The `suggestededits_access` option does not control access to the editor content, however when used in conjunction with the [`readonly`](../editor-important-options/#readonly) option it allows for fine-grained control over user permissions.

When set to:

- `'full'`: The user has full access to the Suggested Edits view, with permission to accept or reject suggestions.
- `'feedback'`: The user has access to the Suggested Edits view, with permission to add feedback to suggestions.
- `'read'`: The user has read-only access to the Suggested Edits view.
- `'none'`: The user has no access to the Suggested Edits view.

**Type:** `String`

**Possible Values**: `'full'`, `'feedback'`, `'read'`, `'none'`

**Default Value**: `'full'`

Example: `suggestededits_access: 'feedback'`
```javascript
tinymce.init({
  selector: 'textarea#suggestededits',  // Change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  suggestededits_access: 'feedback', // Change this value to set the {pluginname} view permissions
  readonly: false // Set to true to restrict editing
});
```
**Example**

```js
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

const tinymceElement = document.querySelector('textarea#suggestededits-access-feedback');
const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits-access-feedback',
  height: 500,
  plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
  toolbar: 'undo redo | suggestededits | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
  readonly: false, // Set to true to prevent edits to the content

  suggestededits_model: model,
  suggestededits_access: 'feedback', // Set this value to restrict the permissions in the Suggested Edits view
  suggestededits_content: 'html',
  view_show: 'suggestededits',
  user_id: 'kai-nakamura',
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`${API_URL}/${userId}`)
        .then((response) => response.json())
        .catch(() => ({ id: userId }))))
});
```
Example: `suggestededits_access: 'read'`
```javascript
tinymce.init({
  selector: 'textarea#suggestededits',  // Change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  suggestededits_access: 'read', // Change this value to set the {pluginname} view permissions
  readonly: false // Set to true to restrict editing
});
```
**Example**

```js
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

const tinymceElement = document.querySelector('textarea#suggestededits-access-read');
const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits-access-read',
  height: 500,
  plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
  toolbar: 'undo redo | suggestededits | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
  readonly: false, // Set to true to prevent edits to the content

  suggestededits_model: model,
  suggestededits_access: 'read', // Set this value to restrict the permissions in the Suggested Edits view
  suggestededits_content: 'html',
  view_show: 'suggestededits',
  user_id: 'kai-nakamura',
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`${API_URL}/${userId}`)
        .then((response) => response.json())
        .catch(() => ({ id: userId }))))
});
```

### `suggestededits_auto_approve`

The `suggestededits_auto_approve` option controls whether edits made during the session by the current user are automatically approved without requiring manual review. With this option enabled any edits by the current user, as set by the [`user_id` option](#user_id), as well as any previous suggestions made by the current user, will be instantly applied, bypassing the review process. This is useful for scenarios where reviews aren’t necessary, such as when creating an initial draft or when the user is a trusted editor.

When set to:

- `false`: All edits require manual approval before being applied.
- `true`: All new edits are automatically approved and applied.

> **Note:** In TinyMCE 8.7, this option controls the default state of the `suggestededits-tracking` toolbar button and menu item. When set to `false`, the `suggestededits-tracking` button will be active by default and edits will appear in the review. When set to `true`, the button will be inactive by default, meaning edits will not appear in the review. Toggling the button or menu item will override the default state set by this option for the current session.
**Type:** `Boolean`

**Default Value**: `false`

Example: `suggestededits_auto_approve: true`
```javascript
tinymce.init({
  selector: 'textarea#suggestededits',  // Change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits suggestededits-tracking',
  suggestededits_auto_approve: true, // Change this value to auto-approve suggested edits
});
```
**Example**

```js
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

const tinymceElement = document.querySelector('textarea#suggestededits-auto-approve');
const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits-auto-approve',
  height: 500,
  plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
  toolbar: 'undo redo | suggestededits suggestededits-tracking | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
  
  suggestededits_model: model,
  suggestededits_access: 'full',
  suggestededits_content: 'html',
  suggestededits_auto_approve: true,
  view_show: 'suggestededits',
  user_id: 'kai-nakamura',
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`${API_URL}/${userId}`)
        .then((response) => response.json())
        .catch(() => ({ id: userId }))))
});
```

### `suggestededits_ai_attribution`

This option controls the display of the AI badge on suggestion cards. An AI badge appears on the cards of edits made with the [TinyMCE AI](../tinymceai/) plugin by default. Set to `false` to hide the badge.

> **Note:** AI-assisted suggestions are always recorded in the model. This option controls only whether the AI badge is displayed.
**Type:** `Boolean`

**Default value:** `true`

#### Example: using `suggestededits_ai_attribution`

```js
tinymce.init({
  selector: 'textarea',  // Change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  suggestededits_ai_attribution: false
});
```

### `view_show`

The [`view_show`](../custom-view/#view_show) option can be used to show the Suggested Edits view when the editor is loaded.

For example:
```js
tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  view_show: 'suggestededits',
  // ... other Suggested Edits options (e.g. suggestededits_model, user_id, fetch_users)
});
```

### `user_id`

This option sets the unique identifier for the current user in the editor. It is used in the the [`UserLookup`](../userlookup/) API.

**Type:** `String`

**Default value:** `'Anonymous'`

Example: using `user_id` option
```javascript
tinymce.init({
  selector: 'textarea',  // Change this value according to your HTML
  user_id: 'james-wilson' // replace this with a unique string to identify the user
});
```

### `fetch_users`

A **required callback function** that fetches user data. This function is called with an array of user IDs and should return a `Promise` that resolves to an array of user objects. The callback is used by the [`UserLookup`](../userlookup/) API. If the returned array does not include all requested user IDs, promises for the missing users will be rejected with a "User {id} not found" error.

**Type:** `Function`

**Parameters:** - `ids` (`Array<string>`): An array of user IDs to fetch.

**Returns:** - `Promise<Array<Object>>`: A promise that resolves to an array of user objects.

Example: using `fetch_users` option
```javascript
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

tinymce.init({
  selector: 'textarea',
  user_id: 'james-wilson',
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`${API_URL}/${userId}`)
        .then((response) => response.json())
        .catch(() => ({ id: userId })))),
});
```
Example: returning user array with validation
```javascript
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

tinymce.init({
  selector: 'textarea',
  user_id: 'james-wilson',
  fetch_users: async (userIds) => {
    const users = await Promise.all(userIds
        .map((userId) =>
        fetch(`${API_URL}/${userId}`)
            .then((response) => response.json())
            .catch(() => ({ id: userId }))));

    return userIds.map(
      (userId) =>
        users.find((user) => user.id === userId)
        || ({ id: userId }) // Still returns a valid user even if it wasn't returned from the server
    );
  },
});
```
Both the [`user_id`](#user_id) and [`fetch_users`](#fetch_users) options are required to configure the [User Lookup API](../userlookup/). This API is used in the Suggested Edits plugin to provide user information for each user who has made a change, allowing other users to see who made which suggestion.

- The current user ID should be set with the [`user_id`](#user_id) option. The user ID should be a unique string that identifies the user, such as a username or an email address.
- The [`fetch_users`](#fetch_users) option is required to provide the name and avatar for users who have made suggestions. This option can be configured to fetch data from a backend service. The `fetch_users` function is given an array of user IDs and should return a promise, which resolves to an array containing data for the requested user IDs.

## Toolbar buttons

The Suggested Edits plugin provides the following toolbar buttons:

| Toolbar button identifier | Description |
| --- | --- |
| `suggestededits` | Opens the Review edits view. |
| `suggestededits-label` | Opens the Review edits view (this button uses text instead of an icon). |
| `suggestededits-tracking` | Toggles the tracking of suggested edits. |

These toolbar buttons can be added to the editor using:

- The [`toolbar`](../toolbar-configuration-options/#toolbar) configuration option.
- The [`quickbars_insert_toolbar`](../quickbars/#quickbars_insert_toolbar) configuration option.
- [Custom Context toolbars](../contexttoolbar/).

## Menu items

The Suggested Edits plugin provides the following menu items:

| Menu item identifier | [Default Menu Location](../menus-configuration-options/#example-the-tinymce-default-menu-items) | Description |
| --- | --- | --- |
| `suggestededits` | View | Opens the Suggested Edits view. |
| `suggestededits-tracking` | *Not Applicable* | Toggles the tracking of suggested edits. |

These menu items can be added to the editor using:

- The [`menu`](../menus-configuration-options/#menu) configuration option.
- The [`contextmenu`](../menus-configuration-options/#contextmenu) configuration option.
- [Custom Menu toolbar buttons](../custom-menu-toolbar-button/).

## Commands

The Suggested Edits plugin provides the following TinyMCE commands.

| Command | Description |
| --- | --- |
| suggestededits | Toggles the Suggested Edits view. |
| suggestededitsToggleTracking | Toggles the tracking of suggested edits. |

Example
```js
tinymce.activeEditor.execCommand('suggestededits');
tinymce.activeEditor.execCommand('suggestededitsToggleTracking');

tinymce.activeEditor.queryCommandState('suggestededitsToggleTracking'); // Returns true if tracking of suggested edits is enabled, otherwise false.
```

## Events

The Suggested Edits plugin provides the following events.

The following events are provided by the [Suggested Edits plugin](#).

| Name | Data | Description |
| --- | --- | --- |
| SuggestedEditsBeginReview | N/A | The Suggested Edits view has opened. |
| SuggestedEditsReviewComplete | N/A | A review in the Suggested Edits view has been completed. |
| SuggestedEditsReviewCancelled | N/A | A review in the Suggested Edits view was cancelled. |
| SuggestedEditsHasChangesUpdate | `hasChanges` | The Suggested Edits model is updated. The `hasChanges` data is a boolean value indicating whether there are suggestions to review. |
| SuggestedEditsTrackingToggle | `tracking` | The tracking state of suggested edits has changed. The `tracking` data is a boolean value indicating whether edits are being tracked. |

## APIs

The Suggested Edits plugin provides the following APIs.

| Name | Arguments | Description |
| --- | --- | --- |
| getModel | N/A | Returns a JSON object representing the current model of the document. |
| setModel | `Object` | Sets the current model of the document. |
| resetModel | N/A | Generates a model from the current content and sets it as the current model, clearing all suggestions. |
| hasChanges | N/A | Returns a boolean value indicating whether the document contains any suggested edits. |

Examples
```js
// Get the current model of the document
tinymce.activeEditor.plugins.suggestededits.getModel();

// Set current model of the document
tinymce.activeEditor.plugins.suggestededits.setModel(model);

// Reset the model to the current content, clearing all suggestions
tinymce.activeEditor.plugins.suggestededits.resetModel();

// Check if document contains changes to be reviewed
tinymce.activeEditor.plugins.suggestededits.hasChanges();
```
`getModel` Example This example demonstrates how to save the current document and model to ensure they are saved synchronously. The current model is retrieved using the `getModel` API.

```js
const tinymceElement = document.querySelector('textarea#suggestededits');
const suggestededits_model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits',  // change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits save',
  suggestededits_model,
  setup: (editor) => {
    editor.on('AddUndo Undo Redo SuggestedEditsBeginReview SuggestedEditsReviewComplete SuggestedEditsReviewCancelled', () => {
      const content = editor.getContent();
      const model = editor.plugins.suggestededits.getModel();
      tinymceElement.value = content;
      tinymceElement.setAttribute('suggestededits-model', JSON.stringify(model));
    });
  }
});
```
`setModel` Example This example demonstrates how to set the model and the document in the editor, in this case fetching them from a server. The `setModel` method sets the current model of the document and the editor content, as generated from that model.

```js
tinymce.init({
  selector: 'textarea#suggestededits',  // change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  setup: (editor) => {
    editor.on('init', () => {
      // Fetch and set the suggested edits model
      fetch(`/api/models/${documentId}`)
        .then((response) => response.json())
        .then((model) => {
          editor.plugins.suggestededits.setModel(model);
        })
        .catch((error) => console.error(`Error fetching model for ${documentId}:`, error));
    });
  }
});
```
`resetModel` Example This example demonstrates how to reset the model to the current content of the editor, clearing all suggestions. The `resetModel` method generates a new model from the current content and sets it as the current model.

```js
tinymce.init({
  selector: 'textarea#suggestededits',  // change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits clearsuggestions',
  setup: (editor) => {
    editor.ui.registry.addButton('clearsuggestions', {
      text: 'Clear Suggestions',
      onAction: () => {
        // Reset the model to the current content, clearing all suggestions
        editor.plugins.suggestededits.resetModel();

        editor.notificationManager.open({
          text: 'All suggestions have been cleared.',
          type: 'info',
          timeout: 5000,
        });
      }
    });
  }
});
```
`hasChanges` Example This example demonstrates how to check if there are any changes in the document that need to be reviewed before saving. The `hasChanges` method is used to determine if there are any unreviewed edits.

```js
tinymce.init({
  selector: 'textarea#suggestededits',  // change this value according to your HTML
  plugins: 'suggestededits',
  toolbar: 'suggestededits',
  setup: (editor) => {
    editor.ui.registry.addButton('save', {
      text: 'Save',
      onAction: () => {
        // Get the current model of the document
        const hasChanges = editor.plugins.suggestededits.hasChanges();

        if (hasChanges) {
          editor.notificationManager.open({
            text: 'There are changes to be reviewed.',
            type: 'warning',
            timeout: 5000,
          });
        } else {
          // Insert save logic here
        }
      }
    });
  }
});
```
