Content for header part.
', content: 'Content for main part.
', leftSide: 'Content for left-side box.
', rightSide: 'Content for right-side box.
' } ); ``` Setting the data through `config.roots.Content for header part.
', element: document.querySelector( '#header' ) }, content: { initialData: 'Content for main part.
', element: document.querySelector( '#content' ) }, leftSide: { initialData: 'Content for left-side box.
', element: document.querySelector( '#left-side' ) }, rightSide: { initialData: 'Content for right-side box.
', element: document.querySelector( '#right-side' ) } } } ); ``` Specify root name when obtaining the data ```js editor.getData( { rootName: 'leftSide' } ); // -> 'Content for left-side box.
' ``` Learn more about using the multi-root editor in its [API documentation](../../api/module_editor-multi-root_multirooteditor-MultiRootEditor.html). source file: "ckeditor5/latest/examples/framework/bottom-toolbar-editor.html" ## Editor with a bottom toolbar and button grouping The following custom editor example showcases an editor instance with the main toolbar displayed at the bottom of the editing window. To make it possible, this example uses the [`DecoupledEditor`](../../api/module_editor-decoupled_decouplededitor-DecoupledEditor.html) with the [main toolbar](../../api/module_editor-decoupled_decouplededitoruiview-DecoupledEditorUIView.html#member-toolbar) injected after the editing root into the DOM. Learn more about the [decoupled UI in CKEditor 5](#ckeditor5/latest/framework/deep-dive/ui/document-editor.html) to find out the details of this process. Additionally, thanks to the flexibility offered by the [CKEditor 5 UI framework](#ckeditor5/latest/framework/architecture/ui-library.html), the main toolbar has been uncluttered by moving buttons related to text formatting into the custom “Formatting options” dropdown. All remaining dropdown and (button) tooltips have been tuned to open upward for the best user experience. Similar effect can also be achieved by using the [built-in toolbar grouping option](#ckeditor5/latest/getting-started/setup/toolbar.html--grouping-toolbar-items-in-dropdowns-nested-toolbars). The presented combination of the UI and editor’s features works best for integrations where text creation comes first and formatting is applied occasionally. Some examples are email applications, (forum) post editors, chats, or instant messaging. You can probably recognize this UI setup from popular applications such as Gmail, Slack, or Zendesk. ### Editor example configuration View editor configuration script ```js import { DecoupledEditor, Plugin, Alignment, Autoformat, Bold, Italic, Strikethrough, Subscript, Superscript, Underline, BlockQuote, clickOutsideHandler, Essentials, Font, Heading, HorizontalLine, Image, ImageCaption, ImageResize, ImageStyle, ImageToolbar, ImageUpload, Indent, Link, List, MediaEmbed, Paragraph, RemoveFormat, Table, TableToolbar, DropdownButtonView, DropdownPanelView, DropdownView, ToolbarView, IconFontColor, registerIcon } from 'ckeditor5'; const fontColorIcon =/* #__PURE__ */ registerIcon( 'fontColor', IconFontColor ); class FormattingOptions extends Plugin { /** * @inheritDoc */ static get pluginName() { return 'FormattingOptions'; } /** * @inheritDoc */ constructor( editor ) { super( editor ); editor.ui.componentFactory.add( 'formattingOptions', locale => { const t = locale.t; const buttonView = new DropdownButtonView( locale ); const panelView = new DropdownPanelView( locale ); const dropdownView = new DropdownView( locale, buttonView, panelView ); const toolbarView = this.toolbarView = dropdownView.toolbarView = new ToolbarView( locale ); // Accessibility: Give the toolbar a human-readable ARIA label. toolbarView.set( { ariaLabel: t( 'Formatting options toolbar' ) } ); // Accessibility: Give the dropdown a human-readable ARIA label. dropdownView.set( { label: t( 'Formatting options' ) } ); // Toolbars in dropdowns need specific styling, hence the class. dropdownView.extendTemplate( { attributes: { class: [ 'ck-toolbar-dropdown' ] } } ); // Accessibility: If the dropdown panel is already open, the arrow down key should focus the first child of the #panelView. dropdownView.keystrokes.set( 'arrowdown', ( data, cancel ) => { if ( dropdownView.isOpen ) { toolbarView.focus(); cancel(); } } ); // Accessibility: If the dropdown panel is already open, the arrow up key should focus the last child of the #panelView. dropdownView.keystrokes.set( 'arrowup', ( data, cancel ) => { if ( dropdownView.isOpen ) { toolbarView.focusLast(); cancel(); } } ); // The formatting options should not close when the user clicked: // * the dropdown or it contents, // * any editing root, // * any floating UI in the "body" collection // It should close, for instance, when another (main) toolbar button was pressed, though. dropdownView.on( 'render', () => { clickOutsideHandler( { emitter: dropdownView, activator: () => dropdownView.isOpen, callback: () => { dropdownView.isOpen = false; }, contextElements: [ dropdownView.element, ...[ ...editor.ui.getEditableElementsNames() ].map( name => editor.ui.getEditableElement( name ) ), document.querySelector( '.ck-body-wrapper' ) ] } ); } ); // The main button of the dropdown should be bound to the state of the dropdown. buttonView.bind( 'isOn' ).to( dropdownView, 'isOpen' ); buttonView.bind( 'isEnabled' ).to( dropdownView ); // Using the font color icon to visually represent the formatting. buttonView.set( { tooltip: t( 'Formatting options' ), icon: fontColorIcon() } ); dropdownView.panelView.children.add( toolbarView ); toolbarView.fillFromConfig( editor.config.get( 'formattingOptions' ), editor.ui.componentFactory ); return dropdownView; } ); } } DecoupledEditor .create( { root: { element: document.querySelector( '#editor-content' ), }, licenseKey: 'GPL', // Or '
Lorem ipsum dolor sit amet...
', type: 'html' } }, { id: 'text4', type: 'text', label: 'Internal note (fetched on demand)', // Note: Since the `data` property is not provided, the content will be retrieved using the `getData()` callback (see below). // This will prevent fetching large content along with the list of resources. }, // URLs to resources. { id: 'url2', type: 'web-resource', label: 'Company brochure in PDF', data: 'https://example.com/brochure.pdf' }, { id: 'url3', type: 'web-resource', label: 'Company website in HTML', data: 'https://example.com/index.html' }, // ... ], // The optional callback to retrieve the content of resources without the `data` property provided by the `getResources()` callback. // When the user picks a specific resource, the content will be fetched on demand (from database or external API) by this callback. // This prevents fetching large resources along with the list of resources. getData: ( id ) => fetchDocumentContent( id ) }, // More context providers... ] }, } } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` #### Attaching the selection automatically By default, the editor selection is attached to the conversation only when the user explicitly clicks the “Ask AI” button. You can change this behavior by enabling the [`config.ai.chat.context.alwaysAddSelection`](../../api/module_ai_aichat_model_aichatcontext-AIChatContextConfig.html#member-alwaysAddSelection) option. When set to `true`, the current editor selection is automatically attached to the conversation whenever the user changes their selection. If the selection becomes collapsed (empty), it is automatically removed. This option requires the [`document`](../../api/module_ai_aichat_model_aichatcontext-AIChatContextConfig.html#member-document) option to be enabled (which is the default). ```js ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), /* ... */ plugins: [ AIChat, AIEditorIntegration, /* ... */ ], ai: { chat: { context: { alwaysAddSelection: true } } } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` #### Attaching resources from a custom UI It’s also possible to allow attaching resources using a custom external UI, for example, a file manager. First, using the [`config.ai.chat.context.customItems`](../../api/module_ai_aichat_model_aichatcontext-AIChatContextConfig.html#member-customItems) configuration option, add a button to the “Add context” dropdown that upon pressing will execute the configured [`callback`](../../api/module_ai_aichat_model_aichatcontext-AIContextCustomItem.html#member-callback) (for example, open custom content manager). Then you can use the [`AIChatContext` class API](../../api/module_ai_aichat_model_aichatcontext-AIChatContext.html) to attach the resource chosen by the user to the conversation. There are various API methods to use depending on the resource type. See an example code below. ```js ClassicEditor .create( { /* ... */ plugins: [ AIChat, AIEditorIntegration, /* ... */ ], ai: { chat: { context: { // Other configuration options... customItems: [ { id: 'open-file-manager', // Unique item ID. label: 'Open file manager', // Button label displayed in the dropdown. icon: IconImage, // Icon displayed next to the label. callback: ( editor: Editor ) => { // `openFileManager()` is provided by you. It opens a custom UI, and returns a promise. // After the user finishes choosing files, the `openFileManager()` promise resolves with data of these files. openFileManager().then( chosenFiles => { editor.plugins.get( 'AIChatController' ).activeConversation.chatContext.addFilesToContext( chosenFiles ); } ); } }, { id: 'open-url-manager', // Unique item ID. label: 'Open URL manager', // Button label displayed in the dropdown. icon: IconURL, // Icon displayed next to the label. callback: ( editor: Editor ) => { // `openURLManager()` is provided by you. It opens a custom UI, and returns a promise. // After the user finishes choosing a URL, the `openURLManager()` promise resolves with proper data. openURLManager().then( chosenURL => { editor.plugins.get( 'AIChatController' ).activeConversation.chatContext.addURLToContext( chosenURL ); } ); } } ] }, } } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` #### Default context To have a reusable set of prompts and files apply to conversations on its own, reference a context from the [Context Library](#ckeditor5/latest/features/ai/ckeditor-ai-context-library.html) in [`config.ai.defaultContext`](../../api/module_ai_aiconfig-AIConfig.html#member-defaultContext) and target the `chat` feature: ```js ClassicEditor .create( { /* ... */ plugins: [ AIChat, AIEditorIntegration, /* ... */ ], ai: { defaultContext: [ { id: 'support-playbook', features: { chat: true } } ] } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` The reference is selected when a conversation is initialized and attached to every message of that conversation. It stays invisible to the user: no chip is added and there is nothing to remove. ##### Limiting the context to a chat shortcut Provide a `RegExp` instead of `true` to attach the context only to conversations started by a matching [chat shortcut](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--chat-shortcuts). The `RegExp` is matched against the shortcut `id`: ```js ai: { chat: { shortcuts: [ { id: 'summarize-for-support', type: 'chat', label: 'Summarize for support', prompt: 'Summarize this document for a support agent.' } ] }, defaultContext: [ { id: 'support-playbook', features: { chat: /^summarize-for-support$/ } } ] } ``` [Learn more about the Context Library](#ckeditor5/latest/features/ai/ckeditor-ai-context-library.html), including the reference shapes and how to attach contexts to the other AI features. ### Welcome message The AI Chat feature allows you to customize the welcome message displayed to users when the chat initializes. You can set the [`config.ai.chat.welcomeMessage`](../../api/module_ai_aichat_aichat-AIChatConfig.html#member-welcomeMessage) option in your editor configuration to provide a custom message. If this option is not set, a default welcome message will be shown. ```js ClassicEditor.create( { /* ... */ plugins: [ AIChat, AIEditorIntegration, /* ... */ ], ai: { chat: { welcomeMessage: 'Hello! How can I assist you today?' // More configuration options... } } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` ### Working with AI-generated changes If you ask the AI for changes to your document, for instance, _“Bold key facts in the document”_, you will receive a series of proposed changes instead of plain text responses: Move your cursor over any change to highlight the section of your document it applies to, helping you identify it among other proposed edits. #### Showing details You can toggle details of the changes by pressing the “Show details” button. By default, you will see detailed information on what exactly was suggested, including additions (green markers), removals (red markers), and formatting changes (blue markers). Click the button again to see a clean, simplified overview of the changes as they’ll appear in your document once accepted. #### Previewing changes Click on the item in the list to display the information window about an individual change with options to [apply it](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--applying-changes), [turn it into a Track Changes suggestion](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--inserting-track-changes-suggestions), or [reject it](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--rejecting-suggestions). You can use this window to browse all proposed changes and work with them one by one. As you navigate through the changes, the window will automatically follow the corresponding sections of the document. > **Note** > > Make sure your integration includes and enables the [`AIEditorIntegration`](../../api/module_ai_aieditorintegration_aieditorintegration-AIEditorIntegration.html) plugin to use this functionality. #### Applying changes Each suggestion on the list comes with an “Apply” button that allows you to apply the change to the document immediately. Click the “Apply all” button in chat to apply all AI suggestions at once. #### Inserting Track Changes suggestions [When Track Changes feature is available in your integration](#ckeditor5/latest/features/ai/ckeditor-ai-integration.html--track-changes-dependency), the “Add as suggestion” button will be available in chat. Clicking it will create a Track Changes suggestion that can later be reviewed or discarded. You can pick the “Suggest all” option under the list to turn all changes suggested by AI into Track Changes suggestions. #### Rejecting suggestions You can click the “Reject change” button to reject AI suggestions you do not want before applying the remaining ones or turning them into Track Changes suggestions. #### Change statuses Once you decide on a change, the action buttons on its item are replaced with a status indicator, so you can always tell how each change ended up: * **Approved** – the change was applied to the document or added as a Track Changes suggestion. * **Rejected** – the change was rejected. * **Outdated** – the change can no longer be applied. This happens when the document has changed in the meantime or the content the change was created for no longer exists. Hover over the indicator to see a tooltip explaining why the change became outdated. ### Chat history All your past conversations appear in the Chat history . Click the button to open the list, where you can reopen, rename, or delete any conversation. Conversations are grouped by date to help you navigate your project easily. You can filter conversations by name using the search field at the top of the user interface. > **Tip** > > You can continue any conversation from the chat history as long as the AI model used for that conversation is [still supported](#ckeditor5/latest/features/ai/ckeditor-ai-integration.html--supported-ai-models) by the feature. Click the conversation in the history to load it in the Chat interface. > **Note** > > The ability to apply suggestions to the document or generate Track Changes suggestions from historical conversations may be restricted in some scenarios: > > * In integrations without [Real-time collaboration](#ckeditor5/latest/features/collaboration/real-time-collaboration/real-time-collaboration.html) enabled, after closing the browser and reopening the AI Chat, previous conversations will no longer interact with the document content. > * In integrations with Real-time collaboration enabled, past conversations will stay interactive as long as the id of the [collaboration#sessions session](#ckeditor5/latest/features/collaboration/real-time-collaboration/users-in-real-time-collaboration.html) stays the same. ### Chat Shortcuts The AI Chat feature can be enhanced by AI Chat Shortcuts – customizable actions that help users trigger common or useful prompts with a single click. These shortcuts appear at the start of a new conversation, making it faster for users to ask questions, request summaries, check grammar, and more. AI Chat Shortcuts require loading the [`AIChatShortcuts`](../../api/module_ai_aichatshortcuts_aichatshortcuts-AIChatShortcuts.html) plugin in your editor configuration. You can configure which shortcuts are available using the [`config.ai.chat.shortcuts`](../../api/module_ai_aichat_aichat-AIChatConfig.html#member-shortcuts) option. This allows you to define shortcut labels, icons, prompts, and the type of action to execute. Shortcuts streamline repetitive queries and encourage best practices in your writing workflows. Example configuration: ```js import { AIChat, AIChatShortcuts, AIEditorIntegration, /* ... */ } from 'ckeditor5-premium-features'; ClassicEditor.create( { /* ... */ // Adding the AIChatShortcuts plugin to enable the feature. plugins: [ AIChat, AIChatShortcuts, AIEditorIntegration, /* ... */ ], /* ... */ ai: { chat: { shortcuts: [ // This shortcut runs an AI Chat prompt with Reasoning and // Web Search features turned on. { id: 'continue-writing', type: 'chat', label: 'Continue writing', prompt: 'Continue writing this document. Match the existing tone, vocabulary level, and formatting. ' + 'Do not repeat or summarize earlier sections. Ensure logical flow and progression of ideas. ' + 'Add approximately 3 paragraphs.', useReasoning: true, useWebSearch: true }, // This shortcut starts proofreading the document by the AI Review feature. { id: 'fix-grammar-and-spelling', type: 'review', label: 'Fix grammar and spelling', commandId: 'correctness' }, // This shortcut switches the UI to the Translate feature and allows // the user decide what to do next (choose a language). { id: 'translate-document', type: 'translate', label: 'Translate document' } ] } } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` > **Note** > > Please keep in mind that specific shortcuts may require additional plugins to be loaded in your editor configuration. For example, the “Fix grammar and spelling” shortcut requires the [`AIReviewMode`](../../api/module_ai_aireviewmode_aireviewmode-AIReviewMode.html) plugin to be loaded that enables the [AI Review](#ckeditor5/latest/features/ai/ckeditor-ai-review.html) feature. > **Note** > > You can also customize the AI Chat [welcome message](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--welcome-message) that users see at the beginning of a new conversation by using the [`config.ai.chat.welcomeMessage`](../../api/module_ai_aichat_aichat-AIChatConfig.html#member-welcomeMessage) option. Use this configuration to highlight specific AI Chat Shortcuts or to explain their purpose. ### Common API AI Chat can be controlled programmatically – send messages, start conversations, and manage chat context from code. > **Experimental** > > Some of our APIs are experimental but ready for production usage. We mark them as experimental to have a possibility to iterate on them faster. That means minor releases without the standard deprecation policy. Breaking changes will always be documented in the changelog with migration guidance. | API | Description | | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | | [`AIChatController#sendMessage()`](../../api/module_ai_aichat_aichatcontroller-AIChatController.html#function-sendMessage) | Programmatically send a message to AI Chat. | | [`AIChatController#startConversation()`](../../api/module_ai_aichat_aichatcontroller-AIChatController.html#function-startConversation) | Start a new chat conversation. | | [`AIChatController#addSelectionToChatContext()`](../../api/module_ai_aichat_aichatcontroller-AIChatController.html#function-addSelectionToChatContext) | Attach the current editor selection as context for the next message. | See the [programmatic usage guide](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html--chat) for details, examples, and a live demo. #### REST API AI Chat conversations are also available via the [Conversations REST API](#cs/latest/guides/ckeditor-ai/conversations.html), which supports multi-turn conversation history, file uploads, and web search capabilities. Use this to build chat-based AI features outside the editor. See the [programmatic documentation](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html) for examples and the [full API reference](https://ai.cke-cs.com). source file: "ckeditor5/latest/features/ai/ckeditor-ai-context-library.html" ## Context library The Context Library stores reusable knowledge on the CKEditor AI service, so the AI features work with your organization’s own rules and reference material instead of generic instructions. A **context** is a named container that can hold reusable prompts, reference files, or both: * **Prompts** – reusable instruction text, such as a tone-of-voice rule, an editorial standard, or a compliance requirement. * **Files** – reference documents, such as a brand guidelines PDF, a product glossary, or a policy handbook. > **Note** > > The word “context” appears in several meanings across the documentation. This guide is about the Context Library. It is not related to the [`Context` class](#ckeditor5/latest/features/collaboration/context-and-collaboration-features.html) that shares plugins between editors, nor to the [resources a user attaches](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--attaching-resources-to-conversations) to an AI Chat conversation. ### How it works 1. An administrator creates a context on the AI service, adds prompts to it, and uploads files – directly or from a URL. See [Creating a context](#cs/latest/guides/ckeditor-ai/context-library.html--creating-a-context) in the Cloud Services documentation for the how-to. 2. An AI request references the context – either the editor sends the reference, or the service applies the context automatically. 3. The service expands the reference before the model sees the request: the context’s prompts are added to the instructions and its files are attached as reference material. > **Important** > > Referencing a context requires the user token to grant access to it, and each reference sent with a request is authorized on its own. Read more about the `ai:contexts` permissions in the [permissions guide](#cs/latest/guides/ckeditor-ai/permissions.html). Resolution happens per call, so a request always uses the current content of the context. Updating a prompt or replacing a file in the library changes the behavior of every request that references it, with no deployment. A context attached this way stays invisible to the user. ### Choosing the right mechanism A context can reach a request at three levels of scope. Pick the one that matches how universal the knowledge is: | Scope | Mechanism | Managed by | Typical case | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | | Whole environment | [Automatic application](#ckeditor5/latest/features/ai/ckeditor-ai-context-library.html--applying-contexts-automatically) | Administrator, on the AI service | Rules that must hold everywhere – house style, compliance. | | Editor instance | [`config.ai.defaultContext`](#ckeditor5/latest/features/ai/ckeditor-ai-context-library.html--attaching-contexts-from-the-editor-configuration) | Integrator, in the editor configuration | Knowledge that depends on the application state – the document type, its workflow status, the current user. | | Single command or call | [A per-invocation reference](#ckeditor5/latest/features/ai/ckeditor-ai-context-library.html--attaching-contexts-in-programmatic-flows) | Integrator, per custom command or programmatic run | Material needed by one specific operation. | ### Applying contexts automatically Some knowledge should shape every AI response in your environment, no matter which feature produced it and who asked. The typical case is a house style: a context holding the style guide file plus a prompt describing when and how the guide applies. With it in place, every conversation, review, action, and translation follows the style guide – and neither the users nor the editor manage anything. This is what the `autoApply` setting of a context does. An administrator enables it on the AI service and the service injects the context into every matching call. No editor configuration is involved, and the editor sends nothing. See [Applying a context automatically](#cs/latest/guides/ckeditor-ai/context-library.html--applying-a-context-automatically) in the Cloud Services documentation to set it up. > **Note** > > Automatic application is global – it affects every matching call in the environment. Note also that it targets the AI service features (`conversations`, `actions.*`, `reviews.*`, `document-processing`), which are named differently than the editor features used in this guide. Use the mechanisms below when the environment-wide scope is too broad and the editor should decide which contexts apply. ### Attaching contexts from the editor configuration The [`config.ai.defaultContext`](../../api/module_ai_aiconfig-AIConfig.html#member-defaultContext) option holds a list of context references that CKEditor AI attaches automatically to the requests made by its features. It is set per editor instance, so the attached knowledge can follow the application state – the type of the edited document, its workflow status, or the current user: ```js // Every document gets the house style guide. const defaultContext = [ { id: 'style-guide' } ]; // Clinical reports additionally get the medical terminology context. if ( documentType === 'clinical-report' ) { defaultContext.push( { id: 'medical-terminology' } ); } ClassicEditor .create( { /* ... */ ai: { defaultContext } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` An entry without a `features` property is attached to every AI feature: [AI Chat](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html), [AI Quick Actions](#ckeditor5/latest/features/ai/ckeditor-ai-actions.html), [AI Review](#ckeditor5/latest/features/ai/ckeditor-ai-review.html), and [AI Translate](#ckeditor5/latest/features/ai/ckeditor-ai-translate.html). #### Context references A context reference points either at a whole context or at a single item inside it: | Reference | Attaches | | ---------------------------------------------------------- | ------------------------------------------- | | `{ id: 'style-guide' }` | Every prompt and every file in the context. | | `{ id: 'style-guide', promptId: 'V1StGXR8_Z5jdHi6B-myT' }` | A single prompt from the context. | | `{ id: 'style-guide', fileId: 'k7Qk2Anpd9WjU7scF3xVv' }` | A single file from the context. | The `promptId` and `fileId` properties are mutually exclusive. All three shapes go into the same `config.ai.defaultContext` list: ```js ClassicEditor .create( { /* ... */ // ... Other configuration options ... ai: { defaultContext: [ // The whole context: every prompt and every file it holds. { id: 'style-guide' }, // A single prompt from another context. { id: 'brand-voice', promptId: 'V1StGXR8_Z5jdHi6B-myT' }, // A single file from another context. { id: 'legal-rules', fileId: 'k7Qk2Anpd9WjU7scF3xVv' } ] } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` The `id` of a context is chosen by whoever creates it, so it can be a readable name such as `style-guide`. The `promptId` and `fileId` values are generated by the service when a prompt or a file is added to a context. Read them from the context itself before referencing a single item. #### Targeting specific features Add a [`features`](../../api/module_ai_aicore_model_aidefaultcontext-AIDefaultContextFeatures.html) property to an entry to narrow down where it applies. Each key targets one AI feature. A key set to `true` attaches the entry to every invocation of that feature. A key set to a `RegExp` attaches it only when one of the invocation IDs matches. A key that is omitted, or set to `false`, excludes the feature: ```js ClassicEditor .create( { /* ... */ // ... Other configuration options ... ai: { defaultContext: [ // Attached to every AI feature. { id: 'style-guide' }, // Attached to every review command, and only to the translate quick actions. { id: 'glossary', features: { review: true, quickActions: /^translate/ } } ] } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` The table below lists the keys and the IDs a `RegExp` is matched against: | Key | Feature | IDs matched by a `RegExp` | | -------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------- | | `chat` | [AI Chat](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html) | The ID of the AI Chat shortcut that started the conversation. | | `quickActions` | [Quick Actions](#ckeditor5/latest/features/ai/ckeditor-ai-actions.html) | The ID of the action and the ID of the group it belongs to. | | `review` | [AI Review](#ckeditor5/latest/features/ai/ckeditor-ai-review.html) | The ID of the review command. | | `translate` | [AI Translate](#ckeditor5/latest/features/ai/ckeditor-ai-translate.html) | The ID of the target language. | The `quickActions`, `review`, and `translate` entries are selected separately for each run. The `chat` entries are selected once, when a conversation is initialized, and then attached to every message of that conversation – so an entry with a `RegExp` matched by the starting chat shortcut applies to the whole conversation, while a conversation started in any other way receives only the entries set to `true`. Each feature guide covers its own configuration, with examples, in detail. #### How references combine References reach a request in a fixed order: first the matching `ai.defaultContext` entries, in configuration order, then any reference the invocation itself carries, such as the `context` of a custom quick action or of an extra review command. ### Using prompts and files in custom actions and reviews A custom quick action or an extra review command can reference a context instead of carrying an inline `prompt` string, so the instruction and its reference material live in the library. This keeps them maintained in one place – they change without a deployment – and out of the frontend: the curated prompt text is not stored in the editor configuration and does not show up in the network traffic of the request. See [custom quick actions](#ckeditor5/latest/features/ai/ckeditor-ai-actions.html--prompt-from-a-context) and [extra review commands](#ckeditor5/latest/features/ai/ckeditor-ai-review.html--prompt-from-a-context) for the configuration. ### Attaching contexts in programmatic flows Driving a feature from code does not change how the mechanisms above apply. A method that starts the user interface flow of a feature attaches the matching `ai.defaultContext` entries, just like the user interface does. A headless run bypasses the user interface, and with it the editor configuration, so it works only with the references the call carries in its `contexts` option. The [programmatic usage guide](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html) documents that option for every flow that accepts it: [chat conversations](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html--chat) – where the passed references are merged with the configured ones rather than replacing them – [quick actions](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html--quick-actions), [reviews](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html--review), [translations](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html--translate), and [document processing](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html--document-processing). ### Common API The Context Library is configured through `config.ai.defaultContext` and can be inspected from code – read the contexts available to the current token and build your own user interface around them. | API | Description | | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | [`config.ai.defaultContext`](../../api/module_ai_aiconfig-AIConfig.html#member-defaultContext) | The list of context references attached automatically to the AI features. | | [`AIContextRef`](../../api/module_ai_aicore_model_aicontextref-AIContextRef.html) | The shape of a single context reference. | | [`AIDefaultContextEntry`](../../api/module_ai_aicore_model_aidefaultcontext-AIDefaultContextEntry.html) | A context reference with an optional `features` narrowing. | | [`AICore#contextLibrary`](../../api/module_ai_aicore_aicore-AICore.html#member-contextLibrary) | The shared context library instance, fetched once for all AI features. | | [`AIContextLibrary#getAllContexts()`](../../api/module_ai_aicore_model_aicontextlibrary-AIContextLibrary.html#function-getAllContexts) | Returns every context the current token can access, for building your own context user interface. | ### Related resources * [Using CKEditor AI programmatically](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html) – drive the AI features and gateways from code. * [Context Library in Cloud Services](#cs/latest/guides/ckeditor-ai/context-library.html) – creating and managing contexts, automatic application, and the REST API details. * [Permissions](#cs/latest/guides/ckeditor-ai/permissions.html) – the `ai:contexts` scopes that control access to contexts. source file: "ckeditor5/latest/features/ai/ckeditor-ai-deployment.html" ## Deployment options CKEditor AI backend is available in two deployment modes: **Cloud (SaaS)** and **On-premises**. Both options provide the same core AI features – [Chat](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html), [Quick Actions](#ckeditor5/latest/features/ai/ckeditor-ai-actions.html), [Review](#ckeditor5/latest/features/ai/ckeditor-ai-review.html), and [Translate](#ckeditor5/latest/features/ai/ckeditor-ai-translate.html) – with the on-premises version offering additional capabilities such as custom AI models and [MCP support](#ckeditor5/latest/features/ai/ckeditor-ai-mcp.html). ### Cloud (SaaS) The Cloud (SaaS) deployment offers the fastest way to get started with CKEditor AI. The AI service is hosted and managed by CKEditor, so there is no server-side setup required on your end. You only need to provide a valid license key and configure the editor-side plugins as described in the [integration guide](#ckeditor5/latest/features/ai/ckeditor-ai-integration.html). For more information about the Cloud AI service, refer to the [CKEditor AI Cloud Services documentation](#cs/latest/guides/ckeditor-ai/overview.html). ### On-premises The on-premises deployment allows you to run the CKEditor AI service on your own infrastructure, including private cloud environments. The service is distributed as Docker images compatible with standard container runtimes. On-premises deployment gives you full control over the AI service, including the ability to use custom AI models and providers, and to extend CKEditor AI with custom tools via [MCP (Model Context Protocol)](#ckeditor5/latest/features/ai/ckeditor-ai-mcp.html). For detailed setup instructions, requirements, and configuration, refer to the [CKEditor AI On-Premises documentation](#cs/latest/onpremises/ckeditor-ai-onpremises/overview.html). #### Connecting the editor to an on-premises service To point the editor to your on-premises AI service, set the [`config.ai.serviceUrl`](../../api/module_ai_aiconfig-AIConfig.html#member-serviceUrl) property to the URL of your on-premises instance: ```js ClassicEditor .create( { licenseKey: 'Lorem ipsum dolor sit amet...
', type: 'html' } }, { id: 'text4', type: 'text', label: 'Internal note (fetched on demand)', // Note: Since the `data` property is not provided, the content will be retrieved using the `getData()` callback (see below). // This will prevent fetching large content along with the list of resources. }, // URLs to resources in different formats { id: 'url1', type: 'web-resource', label: 'Blog post in Markdown', data: 'https://example.com/blog-post.md' }, { id: 'url2', type: 'web-resource', label: 'Company brochure in PDF', data: 'https://example.com/brochure.pdf' }, { id: 'url3', type: 'web-resource', label: 'Company website in HTML', data: 'https://example.com/index.html' }, { id: 'url4', type: 'web-resource', label: 'Terms of service in plain text', data: 'https://example.com/terms-of-service.txt' }, // ... ], // The optional callback to retrieve the content of resources without the `data` property provided by the `getResources()` callback. // When the user picks a specific resource, the content will be fetched on demand (from database or external API) by this callback. // This prevents fetching large resources along with the list of resources. getData: ( id ) => fetchDocumentContent( id ) }, // More context providers... ] } }, // (Optional) The configuration for AI models used across all AI features (Chat and Review). models: { defaultModelId: 'gpt-5.4', displayedModels: [ 'gpt', 'claude' ], showModelSelector: true }, // (Optional) Configure the AI Quick Actions feature by adding a new command. quickActions: { extraCommands: [ // An action that opens the AI Chat interface for interactive conversations. { id: 'explain-like-i-am-five', label: 'Explain like I am five', displayedPrompt: 'Explain like I am five', prompt: 'Explain the following text like I am five years old.', type: 'chat' }, // ... More custom actions ... ], }, } } ) .then( /* ... */ ) .catch( /* ... */ ); ``` ### Configuration #### Supported AI models CKEditor AI ships with curated models from **OpenAI, Anthropic, and Google** on the [Cloud (SaaS) deployment](#ckeditor5/latest/features/ai/ckeditor-ai-deployment.html--cloud-saas). The [On-premises deployment](#ckeditor5/latest/features/ai/ckeditor-ai-deployment.html--on-premises) additionally lets you bring your own models from any provider – Google Cloud, Amazon Bedrock, Azure OpenAI, or any OpenAI-compatible endpoint (e.g. OpenRouter, Together AI, self-hosted). By default, an automatically selected model is used for optimal cost and performance. You can configure the list of available models and the default model using the unified [model configuration](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--configuration), which applies to all AI features (Chat and Review). Here’s a detailed list of available models with their capabilities: | **Model** | **Description** | [Web Search](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--web-search) | [Reasoning](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--reasoning) | [Configuration id](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--configuration) | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | **Auto (default)** | Automatically selects best model for speed, quality, and cost. | Yes | Yes | `'auto'` (also `'agent-1'`, learn more about [compatibility versions](#cs/latest/guides/ckeditor-ai/models.html--model-compatibility-versions)) | | **Custom** | Bring your own models from major clouds (Google Cloud, Bedrock, Azure OpenAI) or any OpenAI-compatible endpoint. [On-premises only](#ckeditor5/latest/features/ai/ckeditor-ai-deployment.html--custom-ai-models). | Per model | Per model | Configured server-side | | **GPT-5.6 Sol** | OpenAI’s frontier model for complex professional work and advanced reasoning | Yes | Yes | `'gpt-5.6-sol'` | | **GPT-5.6 Terra** | Balances intelligence, speed, and cost for everyday tasks | Yes | Yes | `'gpt-5.6-terra'` | | **GPT-5.6 Luna** | OpenAI’s most cost-efficient GPT-5.6 model for high-volume tasks | Yes | Yes | `'gpt-5.6-luna'` | | **GPT-5.5** | OpenAI’s flagship model for advanced reasoning, creativity, and complex tasks | Yes | Yes | `'gpt-5.5'` | | **GPT-5.4** | OpenAI’s flagship model for advanced reasoning, creativity, and complex tasks | Yes | Yes | `'gpt-5.4'` | | **GPT-5.2** | OpenAI’s flagship model for advanced reasoning, creativity, and complex tasks | Yes | Yes | `'gpt-5.2'` | | **GPT-5.1** | OpenAI’s flagship model for advanced reasoning, creativity, and complex tasks | Yes | Yes | `'gpt-5.1'` | | **GPT-5** | OpenAI’s flagship model for advanced reasoning, creativity, and complex tasks | Yes | Yes | `'gpt-5'` | | **GPT-5 Mini** | A lightweight version of GPT-5 – faster, more cost-efficient | Yes | Yes | `'gpt-5-mini'` | | **Claude 4.8 Opus** | Anthropic’s most capable model for extended reasoning and complex tasks | Yes | Yes | `'claude-opus-4-8'` | | **Claude 4.7 Opus** | Anthropic’s most capable model for extended reasoning and complex tasks | Yes | Yes | `'claude-opus-4-7'` | | **Claude 5 Sonnet** | Advanced model with improved creativity, reliability, and reasoning | Yes | Yes | `'claude-5-sonnet'` | | **Claude 4.6 Sonnet** | Advanced model with improved creativity, reliability, and reasoning | Yes | Yes | `'claude-4-6-sonnet'` | | **Claude 4.5 Haiku** | Cost-efficient model for quick interactions with improved reasoning | Yes | Yes | `'claude-4-5-haiku'` | | **Claude 4.5 Sonnet** | Advanced model with improved creativity, reliability, and reasoning | Yes | Yes | `'claude-4-5-sonnet'` | | **Gemini 3.1 Pro** | Google’s advanced model for versatile problem-solving and research | Yes | Yes | `'gemini-3-1-pro'` | | **Gemini 3.5 Flash** | Lightweight Gemini model for fast, cost-efficient interactions | Yes | Yes | `'gemini-3-5-flash'` | | **Gemini 3 Flash** | Lightweight Gemini model for fast, cost-efficient interactions | Yes | Yes | `'gemini-3-flash'` | | **Gemini 2.5 Flash** | Lightweight Gemini model for fast, cost-efficient interactions | Yes | Yes | `'gemini-2-5-flash'` | | **GPT-4.1** | OpenAI’s model for reliable reasoning, speed, and versatility | Yes | No | `'gpt-4.1'` | | **GPT-4.1 Mini** | A lighter variant of GPT-4.1 that balances speed and cost while maintaining solid accuracy | Yes | No | `'gpt-4.1-mini'` | > **Note** > > Learn more about model capabilities such as [Web Search](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--web-search) and [Reasoning](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html--reasoning). This list will continue to grow over time. [Share your feedback on model availability](https://ckeditor.com/contact/). > **Tip** > > You can verify which models are compatible with your service version using a dedicated API. [Learn more](#cs/latest/guides/ckeditor-ai/models.html). #### Cloud version endpoint While using the cloud version of the CKEditor AI feature, you need to provide the service endpoint. ```js ai: { serviceUrl: 'https://ai.cke-cs.com/v1' } ``` If you are using the EU cloud region, remember to adjust the endpoint: ```js ai: { serviceUrl: 'https://ai.cke-cs-eu.com/v1' } ``` #### Document ID The [`config.collaboration.channelId`](../../api/module_collaboration-core_config-RealTimeCollaborationConfig.html#member-channelId) configuration serves as the document identifier corresponding to the edited resource (article, document, etc.) in your application. This ID is essential for maintaining [Chat](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html) history, ensuring that AI conversations are properly associated with the specific document being edited. When users interact with AI features, their chat history is preserved and linked to this document ID. ```js ClassicEditor .create( { /* ... */ collaboration: { channelId: 'DOCUMENT_ID' }, /* ... */ } ) .then( /* ... */ ) .catch( /* ... */ ); ``` > **Note** > > The `channelId` configuration uses the collaboration namespace in the configuration, which may not be immediately understandable for integrators who are not using [collaboration features](#ckeditor5/latest/features/collaboration/context-and-collaboration-features.html--channel-id) in their setup. This namespace is subject to change in future versions as we continue to refine the AI integration architecture. #### Default context The [`config.ai.defaultContext`](../../api/module_ai_aiconfig-AIConfig.html#member-defaultContext) option attaches contexts – named containers of reusable prompts and reference files kept on the AI service – to the requests made by the AI features. The attached contexts stay invisible to the user. Learn more in the [Context library guide](#ckeditor5/latest/features/ai/ckeditor-ai-context-library.html). #### Image analysis The AI service understands images embedded in the document. When the [Chat](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html) or [document processing](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html--document-processing) flow sends the document content, the service downloads the embedded images from their URLs and analyzes them. The AI can then work with the visual content – for example, describe an image, generate a caption for it, or take the image contents into account when editing the surrounding text. Publicly hosted images require no additional setup. However, if the images live behind authentication (like a private CDN or a token-protected asset server), the download performed by the AI service is anonymous and will fail. Use the [`config.ai.extraHttpHeaders`](../../api/module_ai_aiconfig-AIConfig.html#member-extraHttpHeaders) option to provide HTTP headers that the service will attach when downloading the images: ```js ai: { extraHttpHeaders: [ { domain: 'https://assets.example.com/', headers: { authorization: 'Bearer...
', title: 'Article description', label: 'Article description editing area', description: 'Article description with a short summary of the piece.' }, body: { element: document.querySelector( '#body' ), initialData: '...
', title: 'Article body', label: 'Article body editing area', description: 'Main article body — the primary content of the piece.' } }, toolbar: [ 'toggleAi', 'aiQuickActions', /* ... */ ], ai: { container: { type: 'sidebar', element: document.querySelector( '.ai-sidebar' ) } } // ... Other configuration options ... } ) .then( /* ... */ ) .catch( /* ... */ ); ``` #### Multiple editors sharing a `Context` When several editors share a `Context`, the AI feature plugins move to the `Context`-level `config.plugins` array, so a single Chat, History, Review, and Translate UI is shared across all editors. The editor-integration plugins stay on each editor. The `config.ai.container` configuration also sits on the `Context` – the individual editors do not need their own `config.ai` configuration. > **Note** > > The `Context` must declare its own `config.collaboration.channelId`, separate from any channel IDs on the individual editors. AI Chat history is scoped per `Context` (not per editor), and AI will throw `ai-chat-missing-channel-id` if the `Context` has no channel ID configured. ```js Context .create( { plugins: [ AIChat, AIChatHistory, AIChatShortcuts, AIReviewMode, AITranslate ], ai: { container: { type: 'sidebar', element: document.querySelector( '.ai-sidebar' ) } }, collaboration: { channelId: 'shared-context-channel-id' } // ... Other configuration options ... } ) .then( context => Promise.all( [ ClassicEditor.create( { context, attachTo: document.querySelector( '#article-editor' ), plugins: [ AIEditorIntegration, AIQuickActions, TrackChanges, /* ... */ ], root: { title: 'Article body', label: 'Article body editing area', description: 'Main article body — the primary content of the piece.' } } ), ClassicEditor.create( { context, attachTo: document.querySelector( '#sidebar-editor' ), plugins: [ AIEditorIntegration, AIQuickActions, TrackChanges, /* ... */ ], root: { title: 'Related links', label: 'Related links editing area', description: 'Sidebar listing articles and resources related to the main piece.' } } ) ] ) ) .then( /* ... */ ) .catch( /* ... */ ); ``` source file: "ckeditor5/latest/features/ai/ckeditor-ai-overview.html" ## CKEditor AI CKEditor AI empowers authors with real-time AI writing support by integrating AI writing assistance directly into the editing experience. It streamlines content creation and enhances editorial workflows across a wide range of use cases – from productivity boosts and proof-reading to content quality and consistency. If you wish to test CKEditor AI, the access to it is enabled on [the free trial](https://portal.ckeditor.com/signup?callbackUrl=/checkout?plan%3Dfree). ### Demo * **AI Chat** – Use the AI Chat in the side panel to create and edit content on the go with natural language. For example, ask in the chat to add emojis to headings in the content. * **AI Chat History** – Check history for past conversations in the document. * **AI Quick Actions** – Select content and use the balloon toolbar dropdown for Quick Actions and choose from predefined commands. * **AI Review** – Run the review with the improve clarity command. * **AI Translate** – Translate content to various languages with AI-powered translation suggestions. This demo presents a limited set of features. Visit the [feature-rich editor example](#ckeditor5/latest/examples/builds-custom/full-featured-editor.html) to see more in action. ### Why choose CKEditor AI? CKEditor AI is an AI-powered writing assistant that integrates directly into our rich-text editor, CKEditor 5, providing instant text rewriting, summarization, correction, and contextual chat help based on internal style guides. The platform includes automated review tools and enterprise-ready functionality that plugs into existing systems without requiring custom infrastructure. Teams can implement a full suite of AI writing tools in weeks rather than months, delivering streamlined, compliant content workflows that maintain brand consistency and integrate seamlessly with existing document management systems. The core components of CKEditor AI are: * CKEditor 5: A modern rich text editor with dozens of features that improve writing workflows, including collaboration. * AI Service: A state-of-the-art backend AI engine that incorporates multiple models and delivers high-quality content. Available as a [Cloud (SaaS) or on-premises deployment](#ckeditor5/latest/features/ai/ckeditor-ai-deployment.html). The AI Service also provides a REST API. ### CKEditor AI features There are four main features of CKEditor AI. Each feature is a standalone plugin that can be enabled or disabled independently, so you can tailor the AI experience to your needs. Refer to the [integration guide](#ckeditor5/latest/features/ai/ckeditor-ai-integration.html--enabling-individual-features) to learn how to configure them selectively. You can test them all using [the free trial](https://portal.ckeditor.com/signup?callbackUrl=/checkout?plan%3Dfree). #### AI Chat The [CKEditor AI Chat](#ckeditor5/latest/features/ai/ckeditor-ai-chat.html) is a conversational AI that can be used to aid content creation and editing. It introduces a dynamic chat interface designed to facilitate rich, multi-turn interactions between users and an AI Assistant. This capability moves beyond single-prompt content generation, enabling a more interactive and collaborative experience within writing workflows. It also provides context setting and model selection to better suit the needs of specific content and holds chat history for quick reference of previous work. The Chat is also capable of using the web for more up-to-date information and reasoning to think more deeply about the answers and changes it is allowed to make. #### AI Quick actions [Quick actions](#ckeditor5/latest/features/ai/ckeditor-ai-actions.html) streamline routine content transformations by offering one-click AI-powered suggestions directly within the editor. You can also ask questions about your selected text in the Chat to get instant AI insights and analysis. This feature enhances speed, relevance, and usability, particularly for repeatable or simple tasks, while preserving deeper chat-based functionality when needed. #### AI Review The [Review](#ckeditor5/latest/features/ai/ckeditor-ai-review.html) feature provides users with AI-powered quality assurance for their content by running checks for grammar, style, tone, and more. It also introduces an intuitive interface for reviewing and managing AI-suggested edits directly within the document, ensuring content meets professional standards with minimal manual effort. #### AI Translate The [AI Translate](#ckeditor5/latest/features/ai/ckeditor-ai-translate.html) feature provides users with AI-powered translations. It introduces an intuitive interface for reviewing and managing AI-suggested translations directly within the document, ensuring content is translated with minimal manual effort. #### Multi-root and multi-editor setups CKEditor AI features can also run across all roots of a multi-root editor and across multiple editors that share a [`Context`](#ckeditor5/latest/features/collaboration/context-and-collaboration-features.html). [Learn more about AI in multi-root and multi-editor setups](#ckeditor5/latest/features/ai/ckeditor-ai-multi-root-multi-editor-support.html). ### Context library All CKEditor AI features can draw on the Context Library – reusable prompts and reference files kept on the AI service. A context can apply automatically across the whole environment, so the AI output follows your organization’s standards, like the house style guide, with nothing for the users or the editor to manage. [Learn more about the Context Library](#ckeditor5/latest/features/ai/ckeditor-ai-context-library.html). ### Permissions Developers can control access to AI features, models, and capabilities based on user roles, subscription tiers, and organizational requirements. [Learn more about the permissions system](#cs/latest/guides/ckeditor-ai/permissions.html). ### Privacy and data handling You can find detailed information on how CKEditor AI manages your data in [Cloud Services documentation](#cs/latest/guides/ckeditor-ai/overview.html--data-handling-and-security). To learn what information about your editor setup is shared with the AI service, see the [editor feature understanding](#ckeditor5/latest/features/ai/ckeditor-ai-feature-understanding.html) guide. ### Programmatic usage CKEditor AI features can also be controlled entirely from code – useful for building custom UI, automating workflows, or integrating AI capabilities into your application logic beyond the built-in editor toolbar. > **Experimental** > > Some of our APIs are experimental but ready for production usage. We mark them as experimental to have a possibility to iterate on them faster. That means minor releases without the standard deprecation policy. Breaking changes will always be documented in the changelog with migration guidance. The programmatic usage covers two approaches: * **Front-end editor API** – Trigger AI Chat messages and Quick Actions directly from the editor instance. * **REST API** – Call the AI service from your frontend to build AI-powered features around the editor. See the [programmatic usage guide](#ckeditor5/latest/features/ai/ckeditor-ai-programmatic.html) for details, examples, and live demos. ### Known issues and caveats #### Custom HTML elements via General HTML Support CKEditor AI works in editors with [General HTML Support](#ckeditor5/latest/features/html/general-html-support.html) enabled and supports the content it produces. Changes to some GHS elements are limited. `