Autosave
The autosave feature allows you to automatically save the data (for example, send it to the server) when needed. This can happen, for example, when the user changes the content.
# Demo
Type some text in the demo below to try out the autosave feature. Try adding rich content such as images or tables, and observe the feature’s behavior. Demo elements and mechanisms are explained below the editor.
Type some text or input some rich content to test the autosave feature.
Server data:
Type some text or input some rich content to test the autosave feature.
How to understand this demo:
- The status indicator shows if the editor has some unsaved content or pending actions.
- If you drop a big image into this editor, you will see that it is busy during the entire period when the image is being uploaded.
- The editor is also busy when saving the content is in progress (the
save()
's promise was not resolved).
- The autosave feature has a throttling mechanism that groups frequent changes (like typing) into batches.
- The autosave itself does not check whether the data has actually changed. It bases on changes in the model that sometimes may not be “visible” in the data. You can add such a check yourself if you would like to avoid sending the same data to the server twice.
- 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 (for example, 9000ms) and typing something. These actions will make the editor busy for a longer time – try leaving the page then.
This demo presents a limited set of features. Visit the feature-rich editor example to see more in action.
# Installation
⚠️ New import paths
Starting with version 42.0.0, we changed the format of import paths. This guide uses the new, shorter format. Refer to the Packages in the legacy setup guide if you use an older version of CKEditor 5.
After installing the editor, add the feature to your plugin list.
Assuming that you have implemented some form of the saveData()
function that sends the data to your server and returns a promise which is resolved once the data is successfully saved, configuring the Autosave
feature is simple:
import { ClassicEditor, Autosave } from 'ckeditor5';
ClassicEditor
.create( document.querySelector( '#editor' ), {
licenseKey: '<YOUR_LICENSE_KEY>', // Or 'GPL'.
plugins: [ Autosave, /* ... */ ],
autosave: {
// Configuration.
}
} )
.then( /* ... */ )
.catch( /* ... */ );
The autosave feature listens to the editor.model.document#change:data
event, throttles it, and executes the config.autosave.save()
function.
It also listens to the native window#beforeunload
event and blocks it in the following cases:
- The data has not been saved yet (the
save()
function did not resolve its promise or it has not been called yet due to throttling). - Or any of the editor features registered a “pending action” (for example, that an image is being uploaded).
This automatically secures you from the user leaving the page before the content is saved or some ongoing actions like image upload did not finish.
# Configuration
You can configure the minimum period between two save actions using the config.waitingTime
property. This helps to avoid overloading the backend.
One second is the default waiting time before the next save action if nothing has changed after the editor data was last saved.
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
autosave: {
waitingTime: 5000, // in ms
save( editor ) {}
},
} )
.then( /* ... */ )
.catch( /* ... */ );
# Demo code
The demo example at the beginning of this guide shows a simple integration of the editor with a fake HTTP server (which needs 1000ms to save the content). Here is the demo code:
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
autosave: {
save( editor ) {
return saveData( editor.getData() );
}
}
} )
.then( editor => {
window.editor = editor;
displayStatus( editor );
} )
.catch( err => {
console.error( err.stack );
} );
// Save the data to a fake HTTP server (emulated here with a setTimeout()).
function saveData( data ) {
return new Promise( resolve => {
setTimeout( () => {
console.log( 'Saved', data );
resolve();
}, HTTP_SERVER_LAG );
} );
}
// Update the "Status: Saving..." information.
function displayStatus( editor ) {
const pendingActions = editor.plugins.get( 'PendingActions' );
const statusIndicator = document.querySelector( '#editor-status' );
pendingActions.on( 'change:hasAny', ( evt, propertyName, newValue ) => {
if ( newValue ) {
statusIndicator.classList.add( 'busy' );
} else {
statusIndicator.classList.remove( 'busy' );
}
} );
}
# Related features
You can read more about getting and setting data in the Getting started section.
# Common API
The Autosave
plugin registers the AutosaveAdapter
used to save the data.
You can use AutosaveConfig
to control the behavior of the adapter.
# Contribute
The source code of the feature is available on GitHub at https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-autosave.
Every day, we work hard to keep our documentation complete. Have you spotted outdated information? Is something missing? Please report it via our issue tracker.
With the release of version 42.0.0, we have rewritten much of our documentation to reflect the new import paths and features. We appreciate your feedback to help us ensure its accuracy and completeness.