Extensive configuration options for customizing editor behavior, toolbar setup, plugin selection, and feature-specific settings to tailor the editor to specific application needs.
Essential configuration options for editor setup and behavior.
/**
* Main editor configuration interface
*/
interface EditorConfig {
/**
* Array of plugin constructors to load
*/
plugins?: Array<PluginConstructor>;
/**
* Additional plugins to load beyond builtinPlugins
*/
extraPlugins?: Array<PluginConstructor>;
/**
* Plugins to exclude from builtinPlugins
*/
removePlugins?: Array<string | PluginConstructor>;
/**
* Plugin substitutions for customization
*/
substitutePlugins?: Array<SubstitutePluginDefinition>;
/**
* Initial content for the editor
*/
initialData?: string | Record<string, string>;
/**
* UI language configuration
*/
language?: string | LanguageConfig;
/**
* Commercial license key
*/
licenseKey?: string;
/**
* Whether to update source element on destroy
*/
updateSourceElementOnDestroy?: boolean;
/**
* Accessibility label for the editor
*/
label?: string;
}Usage Examples:
// Basic configuration
ClassicEditor.create(element, {
initialData: '<p>Welcome to my editor!</p>',
language: 'en',
licenseKey: 'your-license-key-here'
});
// Plugin management
ClassicEditor.create(element, {
// Add extra plugins
extraPlugins: [CustomPlugin, AnotherPlugin],
// Remove unwanted plugins
removePlugins: ['MediaEmbed', 'Table'],
// Replace built-in plugins
substitutePlugins: [
{ from: 'Link', to: CustomLinkPlugin }
]
});
// Multi-language configuration
ClassicEditor.create(element, {
language: {
ui: 'en',
content: 'es'
}
});Comprehensive toolbar customization options for buttons, separators, and grouping.
/**
* Toolbar configuration options
*/
interface ToolbarConfig {
/**
* Array of toolbar items (button names and separators)
*/
items?: string[];
/**
* Items to remove from default toolbar
*/
removeItems?: string[];
/**
* Items to add to default toolbar
*/
addItems?: string[];
/**
* Whether toolbar should group items when space is limited
*/
shouldNotGroupWhenFull?: boolean;
/**
* Custom view class for toolbar
*/
viewportTopOffset?: number;
}Usage Examples:
// Custom toolbar items
ClassicEditor.create(element, {
toolbar: {
items: [
'undo', 'redo',
'|', // Separator
'heading',
'|',
'bold', 'italic', 'strikethrough',
'|',
'link', 'uploadImage', 'insertTable',
'|',
'bulletedList', 'numberedList',
'|',
'outdent', 'indent',
'|',
'blockQuote', 'mediaEmbed'
]
}
});
// Minimal toolbar
ClassicEditor.create(element, {
toolbar: {
items: ['bold', 'italic', 'link']
}
});
// Remove specific items from default
ClassicEditor.create(element, {
toolbar: {
removeItems: ['uploadImage', 'insertTable', 'mediaEmbed']
}
});
// Add custom items to default
ClassicEditor.create(element, {
toolbar: {
addItems: ['customButton', 'anotherCustomTool']
}
});
// Disable toolbar grouping
ClassicEditor.create(element, {
toolbar: {
shouldNotGroupWhenFull: true
}
});Configuration options for individual plugins included in the build.
/**
* Image plugin configuration
*/
interface ImageConfig {
toolbar?: string[];
upload?: {
types?: string[];
allowMultipleFiles?: boolean;
};
insert?: {
integrations?: string[];
};
styles?: {
options?: Array<{
name: string;
title: string;
icon?: string;
className?: string;
}>;
};
resizeOptions?: Array<{
name: string;
value: string | null;
icon: string;
}>;
resizeUnit?: 'px' | '%';
}
/**
* Table plugin configuration
*/
interface TableConfig {
contentToolbar?: string[];
tableToolbar?: string[];
defaultHeadings?: {
rows?: number;
columns?: number;
};
tableProperties?: {
borderColors?: ColorOption[];
backgroundColors?: ColorOption[];
};
tableCellProperties?: {
borderColors?: ColorOption[];
backgroundColors?: ColorOption[];
};
}
/**
* Heading plugin configuration
*/
interface HeadingConfig {
options?: Array<{
model: string;
view: string | HeadingElementDefinition;
title: string;
class?: string;
}>;
}
/**
* Link plugin configuration
*/
interface LinkConfig {
addTargetToExternalLinks?: boolean;
defaultProtocol?: string;
decorators?: Record<string, LinkDecoratorDefinition>;
}Usage Examples:
// Image configuration
ClassicEditor.create(element, {
image: {
// Image toolbar items
toolbar: [
'imageTextAlternative',
'toggleImageCaption',
'|',
'imageStyle:inline',
'imageStyle:block',
'imageStyle:side',
'|',
'resizeImage'
],
// Upload settings
upload: {
types: ['jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff'],
allowMultipleFiles: true
},
// Style options
styles: {
options: [
'inline', 'alignLeft', 'alignRight',
'alignCenter', 'alignBlockLeft', 'alignBlockRight',
'block', 'side'
]
},
// Resize options
resizeOptions: [
{
name: 'resizeImage:original',
value: null,
icon: 'original'
},
{
name: 'resizeImage:50',
value: '50',
icon: 'medium'
},
{
name: 'resizeImage:75',
value: '75',
icon: 'large'
}
],
resizeUnit: '%'
}
});
// Table configuration
ClassicEditor.create(element, {
table: {
contentToolbar: [
'tableColumn', 'tableRow', 'mergeTableCells',
'tableProperties', 'tableCellProperties'
],
defaultHeadings: {
rows: 1,
columns: 1
},
tableProperties: {
borderColors: [
{ color: 'hsl(0, 0%, 90%)', label: 'Light grey' },
{ color: 'hsl(0, 0%, 60%)', label: 'Dark grey' },
{ color: 'hsl(0, 0%, 30%)', label: 'Very dark grey' },
{ color: 'hsl(0, 0%, 0%)', label: 'Black' }
],
backgroundColors: [
{ color: 'hsl(0, 0%, 100%)', label: 'White' },
{ color: 'hsl(0, 0%, 90%)', label: 'Light grey' },
{ color: 'hsl(120, 75%, 60%)', label: 'Light green' },
{ color: 'hsl(60, 75%, 60%)', label: 'Light yellow' }
]
}
}
});
// Heading configuration
ClassicEditor.create(element, {
heading: {
options: [
{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
{ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' }
]
}
});
// Link configuration
ClassicEditor.create(element, {
link: {
// Add target="_blank" to external links
addTargetToExternalLinks: true,
// Default protocol for URLs without protocol
defaultProtocol: 'https://',
// Link decorators for additional attributes
decorators: {
openInNewTab: {
mode: 'manual',
label: 'Open in a new tab',
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
},
downloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
}
});Configure editor UI language and content language settings.
/**
* Language configuration options
*/
interface LanguageConfig {
/**
* UI language code
*/
ui?: string;
/**
* Content language code
*/
content?: string;
/**
* Text direction for content
*/
textPartLanguage?: Array<{
title: string;
languageCode: string;
textDirection?: 'ltr' | 'rtl';
}>;
}Usage Examples:
// Single language
ClassicEditor.create(element, {
language: 'es' // Spanish UI and content
});
// Separate UI and content languages
ClassicEditor.create(element, {
language: {
ui: 'en', // English interface
content: 'ar' // Arabic content
}
});
// Multi-language content support
ClassicEditor.create(element, {
language: {
ui: 'en',
content: 'en',
textPartLanguage: [
{ title: 'Arabic', languageCode: 'ar', textDirection: 'rtl' },
{ title: 'French', languageCode: 'fr' },
{ title: 'Spanish', languageCode: 'es' }
]
}
});Configure user interface behavior and appearance.
/**
* UI configuration options
*/
interface UIConfig {
/**
* Viewport offset for sticky elements
*/
viewportOffset?: {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
/**
* Poweredby configuration
*/
poweredBy?: {
position?: 'inside' | 'border';
label?: string;
side?: 'left' | 'right';
};
}Usage Examples:
// Viewport offset for sticky toolbar
ClassicEditor.create(element, {
ui: {
viewportOffset: {
top: 50 // Account for fixed header
}
}
});
// Powered by customization
ClassicEditor.create(element, {
ui: {
poweredBy: {
position: 'border',
side: 'right',
label: 'Custom Editor'
}
}
});Advanced configuration options for specific use cases.
/**
* Advanced configuration options
*/
interface AdvancedConfig {
/**
* Mention plugin configuration
*/
mention?: {
feeds: Array<{
marker: string;
feed: string[] | Function;
minimumCharacters?: number;
itemRenderer?: Function;
}>;
};
/**
* Placeholder configuration
*/
placeholder?: string;
/**
* Word count configuration
*/
wordCount?: {
onUpdate?: (stats: { characters: number; words: number }) => void;
displayCharacters?: boolean;
displayWords?: boolean;
};
/**
* Autosave configuration
*/
autosave?: {
save: (editor: Editor) => Promise<void>;
waitingTime?: number;
};
}Usage Examples:
// Placeholder text
ClassicEditor.create(element, {
placeholder: 'Start typing your content here...'
});
// Word count tracking
ClassicEditor.create(element, {
wordCount: {
onUpdate: (stats) => {
document.querySelector('#word-count').textContent =
`${stats.words} words, ${stats.characters} characters`;
},
displayWords: true,
displayCharacters: true
}
});
// Autosave configuration
ClassicEditor.create(element, {
autosave: {
save: async (editor) => {
const data = editor.getData();
await fetch('/api/autosave', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: data })
});
},
waitingTime: 5000 // 5 seconds
}
});
// Complete advanced configuration
ClassicEditor.create(element, {
placeholder: 'Type something amazing...',
mention: {
feeds: [
{
marker: '@',
feed: ['Alice', 'Bob', 'Charlie', 'Diana'],
minimumCharacters: 1
},
{
marker: '#',
feed: async (queryText) => {
const response = await fetch(`/api/tags?q=${queryText}`);
return response.json();
}
}
]
},
wordCount: {
onUpdate: (stats) => {
console.log(`Content: ${stats.words} words, ${stats.characters} chars`);
}
}
});