Integrating CKEditor AI with your application
This guide will take you step-by-step through the process of running CKEditor AI in your editor integration. It also presents possible configuration and customization options.
During the early access stage CKEditor AI supports OpenAI, Anthropic and Gemini. We intend to expand this list of supported agents further with time. In the future, it will also be possible to use custom models and your own API keys in the on-premises version.
After installing the editor, add the feature to your plugin list and provide essential configuration:
import { ClassicEditor } from 'ckeditor5';
import { AIChat, AIQuickActions, AIActions, AIReviewMode, AIBalloon, TrackChanges } from 'ckeditor5-premium-features';
ClassicEditor
.create( document.querySelector( '#editor' ), {
licenseKey: '<YOUR_LICENSE_KEY>',
plugins: [ AIChat, AIQuickActions, AIActions, AIReviewMode, AIBalloon, TrackChanges, /* ... */ ],
// Main feature configuration.
ai: {
// Mandatory UI configuration.
container: {
/* ... */
},
/* ... */
}
} )
.then( /* ... */ )
.catch( /* ... */ );
User interface type must be configured for the AI features to work. Learn more about the available options in the UI placement section or use the sample implementation as a reference.
Read more about installing plugins and toolbar configuration.
An example CKEditor AI configuration is presented below. You can learn more about specific configurations such as UI type, AI Chat, or AI Quick Actions in the later sections of this guide.
To learn more about toolbar configuration, refer to the toolbar configuration guide.
// Simplified integration of Users needed for TrackChanges.
class UsersIntegration extends Plugin {
static get requires() {
return [ 'Users' ];
}
init() {
const users = this.editor.plugins.get( 'Users' );
// Just add a minimal dummy user
users.addUser( { id: 'user-1', name: 'John Doe' } );
users.defineMe( 'user-1' );
}
}
ClassicEditor
.create( editorElement, {
licenseKey: '<YOUR_LICENSE_KEY>',
plugins: [ AIChat, AIQuickActions, AIActions, AIReviewMode, AIBalloon, TrackChanges, UsersIntegration, /* ... */ ],
// Extend the main editor toolbar configuration with additional buttons:
// - 'aiQuickActions': opens the AI Quick Actions menu,
// - 'ask-ai': moves the user focus to the AI Chat,
// - 'improve-writing': executes the "Improve Writing" quick action.
//
// You can add more AI Quick actions to the toolbar configuration if needed.
toolbar: [ 'aiQuickActions', 'ask-ai', /* ... */ ],
// You can use the same AI feature buttons in the balloon toolbar configuration for contextual convenience.
balloonToolbar: {
items: [
/* ... */
'aiQuickActions', 'ask-ai', 'improve-writing', /* ... */
]
},
// Configure the document identifier for AI chat history and context preservation.
// This should be a unique identifier for the document/article being edited.
collaboration: {
channelId: 'channelId' // Replace with your actual document ID
},
// Main configuration of AI features.
ai: {
// Mandatory UI configuration. Displays the AI user interface in a dedicated DOM element.
container: {
type: 'sidebar',
element: document.querySelector( '.ai-sidebar' )
},
// (Optional) Configure the AI Chat feature by configuring available context resources.
chat: {
context: {
// Configuration of the built-in context options.
document: {
enabled: true
},
urls: {
enabled: false
},
files: {
enabled: true
},
// Additional sources for the AI Chat context.
sources: [
{
id: 'my-docs',
label: 'My Documents',
getResources: ( query?: string ) => fetchMyDocuments( query ),
getData: ( id ) => fetchDocumentContent( id )
},
models: {
defaultModelId: OpenAI,
modelSelectorAlwaysVisible: true,
displayedModels: OpenAI, Anthropic, Gemini
}
]
}
},
// (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',
displayedPrompt: 'Explain like I am five',
prompt: 'Explain the following text like I am five years old.',
type: 'CHAT'
},
// ... More custom actions ...
],
},
}
} )
.then( ... )
.catch( ... );
The channelId
parameter serves as the document identifier that uniquely identifies the edited resource (article, document, etc.) in your application. This ID is essential for maintaining chat 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.
collaboration: {
channelId: 'DOCUMENT_ID'
},
The channelId
parameter uses the collaboration namespace in the configuration, which may not be immediately understandable for integrators who are not using collaboration features in their setup. This namespace is subject to change in future versions as we continue to refine the AI integration architecture.
CKEditor AI currently requires the TrackChanges
plugin as a dependency for its core functionality. This dependency is necessary for the AI features to operate properly, even in non-collaborative setups.
Since TrackChanges
requires the Users
plugin, you need to provide a minimal user integration even for non-collaborative setups. The sample implementation above shows a basic UsersIntegration
class that adds a dummy user. For production applications, replace the dummy user with actual user data from your authentication system.
We are planning to split these functionalities in future releases to make the integration more intuitive for users who do not require collaboration features, allowing for a cleaner and more focused setup.
CKEditor AI gives you flexible options for displaying the AI user interface. The config.ai.container
property allows you to choose from three different UI placement modes:
-
AIContainerSidebar
– the AI user interface is displayed in a specific DOM element, allowing you to inject it into your existing user interface.ClassicEditor .create( document.querySelector( '#editor' ), { // ... Other configuration options ... ai: { container: { type: 'sidebar', // Existing DOM element to use as the container for the AI user interface. element: document.querySelector( '#ai-sidebar-container' ) // (Optional) The preferred side of the element to position the tab buttons. side: 'right' }, } } ) .then( /* ... */ ) .catch( /* ... */ );
-
AIContainerOverlay
– the AI user interface is displayed on top of the web page, allowing you to position it on the preferred side of the web page. This mode is best suited for integrations with limited space.ClassicEditor .create( document.querySelector( '#editor' ), { // ... Other configuration options ... ai: { container: { type: 'overlay', side: 'right' }, } } ) .then( /* ... */ ) .catch( /* ... */ );
Learn how to toggle the AI overlay using a dedicated toolbar button.
-
AIContainerCustom
– the AI user interface is displayed in a custom way
allowing you to use the building blocks of the AI user interface to create your own and satisfy specific needs of your application.ClassicEditor .create( document.querySelector( '#editor' ), { // ... Other configuration options ... ai: { container: { type: 'custom' }, } } ) // A custom integration of the AI user interface placing the tab buttons and panels separately in custom containers. .then( editor => { const tabsPlugin = editor.plugins.get( 'AITabs' ); for ( const id of tabsPlugin.view.getTabIds() ) { const tab = tabsPlugin.view.getTab( id ); // Display tab button and panel in a custom container. myButtonsContainer.appendChild( tab.button.element ); myPanelContainer.appendChild( tab.panel.element ); } } ) .catch( /* ... */ );
The overlay user interface type can be easily toggled by the users using the 'toggleAi'
toolbar button. The button becomes available for configuration when the AIEditorIntegration
plugin is enabled.
The following example shows how to enable the 'toggleAi'
button in the main editor toolbar:
import { ClassicEditor } from 'ckeditor5';
import { /* ... */, AIEditorIntegration } from 'ckeditor5-premium-features';
ClassicEditor
.create( document.querySelector( '#editor' ), {
licenseKey: '<YOUR_LICENSE_KEY>',
plugins: [ AIEditorIntegration, /* ... */ ],
// Enable the `'toggleAi'` button in the main editor toolbar.
toolbar: [ 'toggleAi', /* ... */ ],
ai: {
container: {
type: 'overlay'
},
/* ... */
}
} )
.then( /* ... */ )
.catch( /* ... */ );
When the AIEditorIntegration
plugin is enabled, the 'toggleAi'
button gets displayed automatically in the menu bar. To remove this button, please refer to the menu bar configuration guide.
The AIChatConfig
allows for customizing the AI Chat feature.
The config.ai.chat.context
property configures the AI Chat menu for adding resources to the prompt context. This menu allows users to attach additional resources (files, documents, and URLs) to their AI chat prompts, providing the AI with more context for generating responses.
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
ai: {
chat: {
context: {
document: {
enabled: true
},
urls: {
enabled: true
},
files: {
enabled: true
},
sources: [
{
id: 'my-docs',
label: 'My Documents',
getResources: ( query?: string ) => fetchMyDocuments( query ),
getData: ( id ) => fetchDocumentContent( id )
},
]
},
}
}
} )
.then( /* ... */ )
.catch( /* ... */ );
The config.ai.chat.models
setting controls the available models. The property lets the integrator set the default model, tailor the available models list, or turn the list off.
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
ai: {
chat: {
models: {
defaultModelId: 'claude-3-5-haiku',
modelSelectorAlwaysVisible: false,
displayedModels: [ 'gpt', 'claude' ]
}
}
}
} )
.then( /* ... */ )
.catch( /* ... */ );
The AIQuickActionsConfig
allows for customizing the AI Quick Actions feature.
The config.ai.quickActions.extraCommands
property allows you to add new commands to the AI Quick Actions feature.
ClassicEditor
.create( editorElement, {
// ... Other configuration options ...
ai: {
quickActions: {
extraCommands: [
// An action that requires content to be selected in the editor (it transforms the selected content).
{
id: 'add-quote-from-famous-person',
displayedPrompt: 'Add a quote from a famous person',
prompt: 'Add a quote from a known person, which would make sense in the context of the selected text.',
type: AIQuickActionType.ACTION,
model: 'claude-4-sonnet'
},
{
id: 'summarize-in-bullet-points',
displayedPrompt: 'Summarize in 5 bullet points',
prompt: 'Summarize the selected text in 5 bullet points.',
type: AIQuickActionType.CHAT
},
{
id: 'include-more-sarcasm',
displayedPrompt: 'Rewrite adding more sarcasm',
prompt: 'Rewrite using a sarcastic tone.',
type: AIQuickActionType.ACTION,
model: 'claude-4-sonnet'
}
// ... More commands ...
],
},
}
} )
.then( ... )
.catch( ... );
The config.ai.quickActions.removeCommands
property allows you to remove existing commands from the AI Quick Actions feature. Please refer to the API documentation for the list of commands that can be removed.
ClassicEditor
.create( editorElement, {
// ... Other configuration options ...
ai: {
quickActions: {
removeCommands: [
'explain',
'summarize',
// ... More commands to remove ...
]
},
}
} )
.then( ... )
.catch( ... );
The AIReviewModeConfig
allows for customizing the AI Review Mode feature.
The config.ai.reviewMode.translations
property allows you to provide a custom list of translations for the “Translate” check in the AI Review Mode feature.
For instance, the following configuration will add “German” and “French” to the list:
ClassicEditor
.create( editorElement, {
ai: {
reviewMode: {
translations: [
{
id: 'german',
label: 'German'
},
{
id: 'french',
label: 'French'
}
]
}
}
} )
.then( ... )
.catch( ... );