STEP 1. Download CK Editor
We have to options
Option 1) Download through CK Editor online builder: https://ckeditor.com/ckeditor-5/online-builder/
You can select features what you want to have. The benefit of online-builder is that you don't need to setup an environment for npm.
Unfortunately this does not gave me the correct result.
Option 2) Download through NPM
Below is my script to download the necessary assets
#!/bin/bash npm install --save @ckeditor/ckeditor5-build-classic
STEP 2.
Example of the simple editor from CDN
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>CKEditor 5 – Classic editor</title> <script src="https://cdn.ckeditor.com/ckeditor5/40.1.0/classic/ckeditor.js"></script> </head> <body> <h1>Classic editor</h1> <div id="editor"> <p>This is some sample content.</p> </div> <script> ClassicEditor .create( document.querySelector( '#editor' ) ) .catch( error => { console.error( error ); } ); </script> </body> </html>
Example of the full-featured editor from CDN
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <style> #container { width: 1000px; margin: 20px auto; } .ck-editor__editable[role="textbox"] { /* editing area */ min-height: 200px; } .ck-content .image { /* block images */ max-width: 80%; margin: 20px auto; } </style> <div id="container"> <div id="editor"> </div> </div> <!-- The "super-build" of CKEditor 5 served via CDN contains a large set of plugins and multiple editor types. See https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/quick-start.html#running-a-full-featured-editor-from-cdn --> <script src="https://cdn.ckeditor.com/ckeditor5/40.1.0/super-build/ckeditor.js"></script> <!-- Uncomment to load the Spanish translation <script src="https://cdn.ckeditor.com/ckeditor5/40.1.0/super-build/translations/es.js"></script> --> <script> // This sample still does not showcase all CKEditor 5 features (!) // Visit https://ckeditor.com/docs/ckeditor5/latest/features/index.html to browse all the features. CKEDITOR.ClassicEditor.create(document.getElementById("editor"), { // https://ckeditor.com/docs/ckeditor5/latest/features/toolbar/toolbar.html#extended-toolbar-configuration-format toolbar: { items: [ 'exportPDF','exportWord', '|', 'findAndReplace', 'selectAll', '|', 'heading', '|', 'bold', 'italic', 'strikethrough', 'underline', 'code', 'subscript', 'superscript', 'removeFormat', '|', 'bulletedList', 'numberedList', 'todoList', '|', 'outdent', 'indent', '|', 'undo', 'redo', '-', 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'highlight', '|', 'alignment', '|', 'link', 'insertImage', 'blockQuote', 'insertTable', 'mediaEmbed', 'codeBlock', 'htmlEmbed', '|', 'specialCharacters', 'horizontalLine', 'pageBreak', '|', 'textPartLanguage', '|', 'sourceEditing' ], shouldNotGroupWhenFull: true }, // Changing the language of the interface requires loading the language file using the <script> tag. // language: 'es', list: { properties: { styles: true, startIndex: true, reversed: true } }, // https://ckeditor.com/docs/ckeditor5/latest/features/headings.html#configuration 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' }, { model: 'heading5', view: 'h5', title: 'Heading 5', class: 'ck-heading_heading5' }, { model: 'heading6', view: 'h6', title: 'Heading 6', class: 'ck-heading_heading6' } ] }, // https://ckeditor.com/docs/ckeditor5/latest/features/editor-placeholder.html#using-the-editor-configuration placeholder: 'Welcome to CKEditor 5!', // https://ckeditor.com/docs/ckeditor5/latest/features/font.html#configuring-the-font-family-feature fontFamily: { options: [ 'default', 'Arial, Helvetica, sans-serif', 'Courier New, Courier, monospace', 'Georgia, serif', 'Lucida Sans Unicode, Lucida Grande, sans-serif', 'Tahoma, Geneva, sans-serif', 'Times New Roman, Times, serif', 'Trebuchet MS, Helvetica, sans-serif', 'Verdana, Geneva, sans-serif' ], supportAllValues: true }, // https://ckeditor.com/docs/ckeditor5/latest/features/font.html#configuring-the-font-size-feature fontSize: { options: [ 10, 12, 14, 'default', 18, 20, 22 ], supportAllValues: true }, // Be careful with the setting below. It instructs CKEditor to accept ALL HTML markup. // https://ckeditor.com/docs/ckeditor5/latest/features/general-html-support.html#enabling-all-html-features htmlSupport: { allow: [ { name: /.*/, attributes: true, classes: true, styles: true } ] }, // Be careful with enabling previews // https://ckeditor.com/docs/ckeditor5/latest/features/html-embed.html#content-previews htmlEmbed: { showPreviews: true }, // https://ckeditor.com/docs/ckeditor5/latest/features/link.html#custom-link-attributes-decorators link: { decorators: { addTargetToExternalLinks: true, defaultProtocol: 'https://', toggleDownloadable: { mode: 'manual', label: 'Downloadable', attributes: { download: 'file' } } } }, // https://ckeditor.com/docs/ckeditor5/latest/features/mentions.html#configuration mention: { feeds: [ { marker: '@', feed: [ '@apple', '@bears', '@brownie', '@cake', '@cake', '@candy', '@canes', '@chocolate', '@cookie', '@cotton', '@cream', '@cupcake', '@danish', '@donut', '@dragée', '@fruitcake', '@gingerbread', '@gummi', '@ice', '@jelly-o', '@liquorice', '@macaroon', '@marzipan', '@oat', '@pie', '@plum', '@pudding', '@sesame', '@snaps', '@soufflé', '@sugar', '@sweet', '@topping', '@wafer' ], minimumCharacters: 1 } ] }, // The "super-build" contains more premium features that require additional configuration, disable them below. // Do not turn them on unless you read the documentation and know how to configure them and setup the editor. removePlugins: [ // These two are commercial, but you can try them out without registering to a trial. // 'ExportPdf', // 'ExportWord', 'AIAssistant', 'CKBox', 'CKFinder', 'EasyImage', // This sample uses the Base64UploadAdapter to handle image uploads as it requires no configuration. // https://ckeditor.com/docs/ckeditor5/latest/features/images/image-upload/base64-upload-adapter.html // Storing images as Base64 is usually a very bad idea. // Replace it on production website with other solutions: // https://ckeditor.com/docs/ckeditor5/latest/features/images/image-upload/image-upload.html // 'Base64UploadAdapter', 'RealTimeCollaborativeComments', 'RealTimeCollaborativeTrackChanges', 'RealTimeCollaborativeRevisionHistory', 'PresenceList', 'Comments', 'TrackChanges', 'TrackChangesData', 'RevisionHistory', 'Pagination', 'WProofreader', // Careful, with the Mathtype plugin CKEditor will not load when loading this sample // from a local file system (file://) - load this site via HTTP server if you enable MathType. 'MathType', // The following features are part of the Productivity Pack and require additional license. 'SlashCommand', 'Template', 'DocumentOutline', 'FormatPainter', 'TableOfContents', 'PasteFromOfficeEnhanced' ] }); </script> </body> </html>
Implementing upload feature with CKEditor 5
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CKEditor 5 File Upload</title> <script src="https://cdn.ckeditor.com/ckeditor5/44.0.0/classic/ckeditor.js"></script> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> </head> <body> <textarea id="editor"></textarea> <script> ClassicEditor .create(document.querySelector('#editor'), { // CKEditor configuration options }) .catch(error => { console.error(error); }); function uploadFile(file) { const formData = new FormData(); formData.append('file', file); $.ajax({ url: 'upload.php', // Your PHP script for handling uploads type: 'POST', data: formData, processData: false, contentType: false, success: function (data) { console.log('File uploaded successfully:', data); }, error: function (error) { console.error('Error uploading file:', error); } }); } // Listen for the 'change' event on the file input in the editor document.querySelector('#editor input[type="file"]').addEventListener('change', (event) => { const file = event.target.files[0]; if (file) { uploadFile(file); } }); </script> </body> </html>
upload.php
<?php // Check if the file was uploaded without errors if ($_FILES['file']['error'] === UPLOAD_ERR_OK) { $uploadDir = 'uploads/'; // Adjust the upload directory $uploadFile = $uploadDir . basename($_FILES['file']['name']); // Move the uploaded file to the desired directory if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadFile)) { echo json_encode(['success' => true, 'url' => $uploadFile]); } else { echo json_encode(['success' => false, 'error' => 'Failed to move the uploaded file.']); } } else { echo json_encode(['success' => false, 'error' => 'File upload failed.']); } ?>