# Bookmarks

The bookmarks feature allows for adding and managing the bookmarks anchors attached to the content of the editor. These provide fast access to important content sections, speed up the editing navigation and contribute to a more efficient content creation.

> **Unlock this feature with selected CKEditor Plans**
>
> Try all premium features – no credit card needed.
>
> [Sign up for a free trial ](https://portal.ckeditor.com/checkout?plan=free)[Select a Plan](https://ckeditor.com/pricing/)

<a id="demo">

## Demo

Use the bookmark toolbar button in the editor below to see the feature in action. Or use the “Insert” command from the menu bar to add a bookmark. Add a unique name to identify the bookmark (for example, `Rights`). You can change the bookmark’s name or remove it by clicking the bookmark icon inside the content.

To use the bookmark as an anchor in the content, add a link and put the bookmark name as target. In the example below it could be `#Rights`. The link insertion panel will display all bookmarks available in the edited content (see the [Integration with the link feature](#integration-with-the-link-feature) section below).

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

This demo presents a limited set of features. Visit the [feature-rich editor example](../examples/builds-custom/full-featured-editor.md) to see more in action.

<a id="handling-the-anchor-markup">

## Handling the anchor markup

Do not worry about setting a bookmark inside an empty paragraph. The block with the `<a>` element will not be rendered in the final content (for example for printing).

The feature converts anchors into bookmarks during the [initialization of the editor](../getting-started/setup/getting-and-setting-data.md#initializing-the-editor-with-data) or while [replacing the editor data with `setData()`](../getting-started/setup/getting-and-setting-data.md#replacing-the-editor-data-with-setdata). The notation based on the `id` attribute in an `a` HTML element without a `href` attribute is converted. Similar notations meet the conditions, too:

* an `a` HTML element with a `name` attribute,
* an `a` HTML element with the same `name` and `id` attributes,
* an `a` HTML element with different `name` and `id` attributes.

By default, all bookmarks created in the editor only have the `id="..."` attribute in the [editor data](../getting-started/setup/getting-and-setting-data.md#getting-the-editor-data-with-getdata).

<a id="integration-with-the-link-feature">

## Integration with the link feature

Bookmarks integrate with [links](link.md), providing a smooth linking experience. If you have any bookmarks in your content, you can access the “Bookmarks” panel available during link creation. It will display all bookmarks available in the edited content. Choose one of the anchors from the list and use it as a link target.

<a id="installation">

## Installation

After [installing the editor](../getting-started/installation/cloud/quick-start.md), add the feature to your plugin list and toolbar configuration:

**NPM**

```js
import { ClassicEditor, Bookmark } from 'ckeditor5';

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>', // Or 'GPL'.
		plugins: [ Bookmark, /* ... */ ],
		toolbar: [ 'bookmark', /* ... */ ]
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

**CDN**

```js
const { ClassicEditor, Bookmark } = CKEDITOR;

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>',
		plugins: [ Bookmark, /* ... */ ],
		toolbar: [ 'bookmark', /* ... */ ]
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<a id="configuration">

## Configuration

By default, the conversion of wrapped anchors is turned on. It allows to convert non-empty anchor elements into bookmarks. For example:

```html
<a id="foo">Foo bar baz</a>
```

will be converted into a bookmark and the output will look like on the example below:

```html
<a id="foo"></a>Foo bar baz
```

You can disable the automatic conversion by setting the [`config.bookmark.enableNonEmptyAnchorConversion`](../api/module_bookmark_bookmarkconfig-BookmarkConfig.md#member-enableNonEmptyAnchorConversion) to `false` in the editor configuration.

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		bookmark: {
			enableNonEmptyAnchorConversion: false
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<a id="bookmark-toolbar-configuration">

## Bookmark toolbar configuration

The bookmark UI contains a contextual toolbar that appears when a bookmark is selected. You can configure what items appear in this toolbar using the [`config.bookmark.toolbar`](../api/module_bookmark_bookmarkconfig-BookmarkConfig.md#member-toolbar) option.

The following toolbar items are available:

* `'bookmarkPreview'` – Shows the name of the bookmark.
* `'editBookmark'` – Opens a form to edit the bookmark name.
* `'removeBookmark'` – Removes the bookmark.

By default, the bookmark toolbar is configured as follows:

```js
ClassicEditor
	.create( {
		bookmark: {
			toolbar: [ 'bookmarkPreview', '|', 'editBookmark', 'removeBookmark' ]
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<a id="custom-toolbar-items">

### Custom toolbar items

You can extend the bookmark toolbar with custom items by registering them in the [component factory](../api/module_ui_componentfactory-ComponentFactory.md) and adding them to the toolbar configuration.

Here is an example of registering a custom component:

```js
class MyCustomPlugin extends Plugin {
	init() {
		const editor = this.editor;

		editor.ui.componentFactory.add( 'myCustomBookmarkInfo', locale => {
			const button = new ButtonView( locale );
			const bookmarkCommand = editor.commands.get( 'insertBookmark' );

			button.bind( 'isEnabled' ).to( bookmarkCommand, 'value', href => !!href );
			button.bind( 'label' ).to( bookmarkCommand, 'value' );

			button.on( 'execute', () => {
				// Add your custom component logic here
			} );

			return button;
		} );
	}
}
```

Once registered, the component can be used in the toolbar configuration:

```js
ClassicEditor
	.create( {
		plugins: [ MyCustomPlugin, /* ... */ ],
		bookmark: {
			toolbar: [ 'myCustomBookmarkInfo', '|', 'editBookmark', 'removeBookmark' ]
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<a id="bookmarks-on-blocks">

## Bookmarks on blocks

At this time, if a bookmark is attached to a block, it appears before it. However, we plan to expand this solution in the future. We invite you to help us [gather feedback for linking directly to blocks and auto generating IDs](https://github.com/ckeditor/ckeditor5/issues/17264).

<a id="related-features">

## Related features

Here are some other CKEditor 5 features that you can use similarly to the bookmark plugin to cross-link and structure your text better:

* The [link feature](link.md) allows adding local and global URLs to the content.
* The [document outline](document-outline.md) displays the list of sections (headings) of the document next to the editor.
* The [table of contents](document-outline.md) lets you insert a widget with a list of headings (section titles) that reflects the structure of the document.

<a id="common-api">

## Common API

The [`Bookmark`](../api/module_bookmark_bookmark-Bookmark.md) plugin registers the `'bookmark'` UI button component implemented by the [bookmark UI feature](../api/module_bookmark_bookmarkui-BookmarkUI.md), and the following commands:

* the `'insertBookmark'` command implemented by the [editing feature](../api/module_bookmark_insertbookmarkcommand-InsertBookmarkCommand.md).
* the `'updateBookmark'` command implemented by the [editing feature](../api/module_bookmark_updatebookmarkcommand-UpdateBookmarkCommand.md).

> **Note**
>
> We recommend using the official [CKEditor 5 inspector](../framework/development-tools/inspector.md) for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.

<a id="contribute">

## Contribute

The source code of the feature is available on GitHub at <https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-bookmark>.

---

Full index of the CKEditor 5 documentation: [llms.txt](../../llms.txt)
