CK Editor online builder: https://ckeditor.com/ckeditor-5/online-builder/
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.']); } ?>