CKEditor 5 allows you to retrieve the data from and save it to your server (or to your system in general) in various ways. In this guide you can learn about the available options along with their pros and cons.
# Automatic integration with HTML formsThis is the classic way of integrating the editor. It is typically used in simpler CMSes, forums, comment sections, etc.
This approach is only available in the Classic editor and only if the editor was used to replace a element:
CKEditor 5 - Classic editorClassic editor<p>This is some sample content.</p>ClassicEditor.create( document.querySelector( '#editor' ) ).catch( error => {console.error( error );} );Classic editor will automatically update the value of the element once the user submits the form. You do not need any additional JavaScript code to send the editor data to the server.
In your HTTP server, you can now read the editor data from the content variable of the POST request. For instance, in PHP, you can get it in this way:
Please note that the replaced element is updated automatically by CKEditor straight before the submission. If you need to access the value programatically with JavaScript (e.g. in the onsubmit handler to validate the entered data), there is a chance that the element would still store the original data. In order to update the value of the replaced , use the editor.updateSourceElement() method.
If you need to get the actual data from CKEditor at any moment using JavaScript, use the editor.getData() method as described in the next section.
When you print the data from the database to a element in an HTML page, you need to encode it correctly. For instance, if you use PHP then a minimal solution would look like this:
Thanks to that, the will be printed out like this:
<p>This is some sample content.</p>Instead of being printed like this:
This is some sample content.
While simple content like mentioned above does not itself require to be encoded, encoding the data will prevent losing text like “ {window.editor = editor;handleStatusChanges( editor );handleSaveButton( editor );handleBeforeunload( editor );} ).catch( err => {console.error( err.stack );} );// Handle clicking the "Save" button by sending the data to a// fake HTTP server (emulated here with setTimeout()).function handleSaveButton( editor ) {const saveButton = document.querySelector( '#save' );const pendingActions = editor.plugins.get( 'PendingActions' );saveButton.addEventListener( 'click', evt => {const data = editor.getData();// Register the action of saving the data as a "pending action".// All asynchronous actions related to the editor are tracked like this,// so later on you only need to check `pendingActions.hasAny` to check// whether the editor is busy or not.const action = pendingActions.add( 'Saving changes' );evt.preventDefault();// Save the data to a fake HTTP server.setTimeout( () => {pendingActions.remove( action );// Reset isDirty only if the data did not change in the meantime.if ( data == editor.getData() ) {isDirty = false;}updateStatus( editor );}, HTTP_SERVER_LAG );} );}// Listen to new changes (to enable the "Save" button) and to// pending actions (to show the spinner animation when the editor is busy).function handleStatusChanges( editor ) {editor.plugins.get( 'PendingActions' ).on( 'change:hasAny', () => updateStatus( editor ) );editor.model.document.on( 'change:data', () => {isDirty = true;updateStatus( editor );} );}// If the user tries to leave the page before the data is saved, ask// them whether they are sure they want to proceed.function handleBeforeunload( editor ) {const pendingActions = editor.plugins.get( 'PendingActions' );window.addEventListener( 'beforeunload', evt => {if ( pendingActions.hasAny ) {evt.preventDefault();}} );}function updateStatus( editor ) {const saveButton = document.querySelector( '#save' );// Disables the "Save" button when the data on the server is up to date.if ( isDirty ) {saveButton.classList.add( 'active' );} else {saveButton.classList.remove( 'active' );}// Shows the spinner animation.if ( editor.plugins.get( 'PendingActions' ).hasAny ) {saveButton.classList.add( 'saving' );} else {saveButton.classList.remove( 'saving' );}}
How to understand this demo:
The button changes to “Saving…” when the data is being sent to the server or there are any other pending actions (e.g. an image being uploaded).You will be asked whether you want to leave the page if an image is being uploaded or the data has not been saved successfully yet. You can test that by dropping a big image into the editor or changing the “HTTP server lag” to a high value (e.g. 9000ms) and clicking the “Save” button. These actions will make the editor “busy” for a longer time — try leaving the page then.Change the content of this editor, then save it on the server.
HTTP server lag (ms):Server data:
Change the content of this editor, then save it on the server.
Every day, we work hard to keep our documentation complete. Have you spotted an outdated information? Is something missing? Please report it via our issue tracker.