Integrating CKEditor 5 with Svelte from CDN
Svelte is a modern JavaScript compiler that builds highly optimized, reactive web applications. Unlike traditional frameworks, Svelte shifts most of the work from runtime to build time, resulting in highly efficient applications. CKEditor 5 rich-text editor can be easily integrated with Svelte applications, providing powerful rich text editing capabilities to your projects.
To use our Cloud CDN services, create a free account. Learn more about license key activation.
This guide will show you how to integrate CKEditor 5 into a Svelte application using the CDN distribution. If you are new to Svelte, check out their official tutorial.
First, create a new Svelte project using Vite:
npm create vite@latest ckeditor-svelte -- --template svelte
cd ckeditor-svelte
npm install
When completed, the folder structure of your project should resemble this one:
├── node_modules/
├── public/
├── src/
│ ├── lib/
│ │ └── Editor.svelte
│ ├── App.svelte
│ ├── main.js
│ └── ...
├── index.html
├── package.json
├── vite.config.js
├── svelte.config.js
└── ...
The integration requires:
- Modifying
index.htmlto include CKEditor 5 scripts and style sheets - Creating the
src/lib/Editor.sveltecomponent - Updating the
src/App.sveltemain application component
Let’s implement these changes next.
To load CKEditor 5 from CDN, modify the main HTML file of your project (index.html) to include the necessary scripts and style sheets:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CKEditor 5 + Svelte</title>
<!-- CKEditor 5 CSS -->
<link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5/47.6.0/ckeditor5.css" />
<link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5-premium-features/47.6.0/ckeditor5-premium-features.css" />
<!-- CKEditor 5 Scripts -->
<script src="https://cdn.ckeditor.com/ckeditor5/47.6.0/ckeditor5.umd.js"></script>
<script src="https://cdn.ckeditor.com/ckeditor5-premium-features/47.6.0/ckeditor5-premium-features.umd.js"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
The premium features scripts and style sheets are optional and used in this guide to demonstrate a complete integration. You can use just the open-source features if you prefer.
Create a new file src/lib/Editor.svelte with the following content:
<script>
import { onMount, onDestroy } from 'svelte';
let { value = $bindable('') } = $props();
let editorContainer;
let editorInstance = $state(null);
let isDestroyed = false;
// Sync external value changes to the editor.
$effect(() => {
if (editorInstance && editorInstance.getData() !== value) {
editorInstance.setData(value);
}
});
onMount( async () => {
const { ClassicEditor, Essentials, Bold, Italic, Font, Paragraph } = CKEDITOR;
const { FormatPainter } = CKEDITOR_PREMIUM_FEATURES;
// Capture value before async initialization.
let initialData = value;
editorInstance = await ClassicEditor.create( editorContainer, {
licenseKey: '<YOUR_LICENSE_KEY>', // Replace with your license key
plugins: [ Essentials, Bold, Italic, Font, Paragraph, FormatPainter ],
toolbar: [
'undo', 'redo', '|', 'bold', 'italic', '|',
'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', '|',
'formatPainter'
],
initialData
} );
// Prevent memory leaks if unmounted during creation.
if (isDestroyed) {
await editorInstance.destroy();
return;
}
// Update the bound value when editor content changes.
editorInstance.model.document.on( 'change:data', () => {
value = editorInstance.getData();
} );
} );
onDestroy( () => {
// Clean up editor instance on unmount.
editorInstance?.destroy().catch( err => console.error( err ) );
editorInstance = null;
isDestroyed = true;
} );
</script>
<div bind:this={editorContainer}></div>
To listen for editor content changes, use the change:data event on editor.model.document as shown above. Do not use editor.on( 'change:data', ... ) directly on the editor instance – that listens for observable property changes on the editor object, not for content edits made by the user.
Now, modify the main App.svelte file to use our editor component:
<script>
import Editor from './lib/Editor.svelte';
let content = $state('<p>Enter your content here...</p>');
</script>
<main>
<h1>CKEditor 5 + Svelte</h1>
<div class="editor-wrapper">
<Editor bind:value={content} />
</div>
</main>
<style>
.editor-wrapper {
width: 800px;
}
:global(.ck.ck-editor__editable) {
height: 200px;
background-color: white;
color: #333;
}
</style>
You can now run the dev server to see the editor in action:
npm run dev
The Svelte HTML editor integration follows these key steps:
- Static loading: CKEditor 5 scripts and styles are loaded from CDN in the HTML file.
- Editor initialization: The editor is created with the specified configuration when the component mounts.
- Two-way data binding: The editor listens to
change:dataevents oneditor.model.documentto update the bound value, while a Svelte$effectsyncs external value changes back to the editor. - Cleanup: Resources are properly released when the component is destroyed.
Basic styling is provided in the App.svelte component to ensure proper display in various environments, especially when using dark themes:
.editor-wrapper {
width: 800px;
}
:global(.ck.ck-editor__editable) {
height: 200px;
background-color: white;
color: #333;
}
- Explore the Getting and setting data guide to learn how to handle content.
- Learn more about configuration options to customize your editor.
- Check the features documentation to add more functionality to your editor.