Besides setting user permissions per doc, the document ID is also useful for persisting the document content. Now on the screen, I've got two documents set up, each with different ID query variables set in the URL. And these two different documents do indeed have different content. Notice this has one UUID printed to the page, which I just typed in and copied from the URL.
and this one has another. Of course, any other content that we type in here is unique per that document as well. If I refresh the page, the different content even persists. But this is only a temporary storage solution that CKEditor provides to better facilitate collaboration.
Let me explain further. CK Editor does persist collaboration data, such as comments, revisions, and so on, indefinitely, but document content will be deleted 24 hours after the last user exits the session. Alternatively, there's also an option to store the collaboration data on your own servers. For us, though, we'll let CK Editor handle the collab data, but we still need to handle the document content ourselves.
So, how do we make the content permanent? This page in the CKEditor docs shows four different possible solutions. The first solution is based on server-to-server communication, where your server initiates the request to the CKEditor server for document information. The next is a server-to-server solution where CKEditor server initiates request to your server to save the newly updated docs.
The third is a solution that doesn't require you to save documents on your server at all, but instead relies on long-term storage provided by CK editor servers. Lastly, and the easiest to implement, is the autosave plugin. In this approach, the client side is responsible for sending the document to your own server for saving. Each of these approaches has its own pros and cons.
You can read more about them all using the link in the description below. Plus, fine detailed talks on how to implement each one. However, for this course, we're gonna go with the autosave plugin. Back inside of the editor component, you can see that the plugin is already installed, but it's not really doing anything at this point.
Let's fix that in this lesson. Underneath the collaboration settings inside of this editor config, let's set the autosave property and define an async save function. This function will be passed the CKEditor instance when it's called on a regular interval by the library. And here we can make a request to our own server with the document content to persist however we'd like.
Since we're using Nuxt, we can use another Nuxt API endpoint in the built-in $fetch function. I'll make the request to an endpoint called slash API slash docs slash the dynamic document ID. We'll create the actual API endpoint handler in just a moment. Next, I'll make the request with the post method.
And for the body, we'll send a JSON object with a document property equal to the data from the editor. gitdata. Over in the server API directory, I'll just paste in some code quickly to a new file under slash docs slash id dot post dot ts. The dot post in the file name says that we should only respond to post type requests.
In the handler, we get the ID from the URL as a route param, and we get the document content from the post body. If the document or the document ID are missing, we throw an error, but if the data set is all there, we'll use Nuxt's built-in key value storage to save the document under a key equal to its ID. data. In your app, of course, your server-side solution will depend completely on your server-side setup.
You might save your documents to key value storage, or to a relational database. Back in the browser though, let's see what happens when I make some changes. Okay, added a new short little paragraph here, and then back inside of the IDE. After waiting for just a moment, the file is not popping in for some reason.
Let's check the console real quick. Aha, fetch error, get, blah, blah, blah. No response, cannot have a body. view?
We misspelled method as method. Save that, go back and refresh the page, and make another edit. And there we go. data folder, and there is our document stored in a file named after its ID.
The content of that file, of course, is the actual document content. The last step in this process is retrieving the saved content from storage to set the editor content on page load. Let me quickly paste in another API endpoint to do this for us. ts.
It does just the opposite of the post request. That is, it reads the data from storage instead of writing it. Of course, just above we do the same checks as we did before, making sure document ID is passed correctly. Now back in the editor component, just after defining the component prompts, let's fetch the data from the API endpoint with Nuxt's useFetchComposable.
Then we'll await the result and extract the data as a variable called documentData. Then let's search the file for the variable called initialData. When we pasted this from the builder, it came with some boilerplate HTML, which is why we started with some content in the editor so far. And you can see it hard coded right here.
But now let's set this to the saved data from our KB storage. In the browser, all of our edits still persist. And in the file system, that is our permanent storage solution, the updates are reflected as well. At this point, we're no longer relying on the temporary storage from CK Editor, and I can open my docs days, weeks, or even months from now and still have the right content.
Besides setting user permissions per doc, the document ID is also useful for persisting the document content. Now on the screen, I've got two documents set up, each with different ID query variables set in the URL. And these two different documents do indeed have different content. Notice this has one UUID printed to the page, which I just typed in and copied from the URL.
and this one has another. Of course, any other content that we type in here is unique per that document as well. If I refresh the page, the different content even persists. But this is only a temporary storage solution that CKEditor provides to better facilitate collaboration.
Let me explain further. CK Editor does persist collaboration data, such as comments, revisions, and so on, indefinitely, but document content will be deleted 24 hours after the last user exits the session. Alternatively, there's also an option to store the collaboration data on your own servers. For us, though, we'll let CK Editor handle the collab data, but we still need to handle the document content ourselves.
So, how do we make the content permanent? This page in the CKEditor docs shows four different possible solutions. The first solution is based on server-to-server communication, where your server initiates the request to the CKEditor server for document information. The next is a server-to-server solution where CKEditor server initiates request to your server to save the newly updated docs.
The third is a solution that doesn't require you to save documents on your server at all, but instead relies on long-term storage provided by CK editor servers. Lastly, and the easiest to implement, is the autosave plugin. In this approach, the client side is responsible for sending the document to your own server for saving. Each of these approaches has its own pros and cons.
You can read more about them all using the link in the description below. Plus, fine detailed talks on how to implement each one. However, for this course, we're gonna go with the autosave plugin. Back inside of the editor component, you can see that the plugin is already installed, but it's not really doing anything at this point.
Let's fix that in this lesson. Underneath the collaboration settings inside of this editor config, let's set the autosave property and define an async save function. This function will be passed the CKEditor instance when it's called on a regular interval by the library. And here we can make a request to our own server with the document content to persist however we'd like.
Since we're using Nuxt, we can use another Nuxt API endpoint in the built-in $fetch function. I'll make the request to an endpoint called slash API slash docs slash the dynamic document ID. We'll create the actual API endpoint handler in just a moment. Next, I'll make the request with the post method.
And for the body, we'll send a JSON object with a document property equal to the data from the editor. gitdata. Over in the server API directory, I'll just paste in some code quickly to a new file under slash docs slash id dot post dot ts. The dot post in the file name says that we should only respond to post type requests.
In the handler, we get the ID from the URL as a route param, and we get the document content from the post body. If the document or the document ID are missing, we throw an error, but if the data set is all there, we'll use Nuxt's built-in key value storage to save the document under a key equal to its ID. data. In your app, of course, your server-side solution will depend completely on your server-side setup.
You might save your documents to key value storage, or to a relational database. Back in the browser though, let's see what happens when I make some changes. Okay, added a new short little paragraph here, and then back inside of the IDE. After waiting for just a moment, the file is not popping in for some reason.
Let's check the console real quick. Aha, fetch error, get, blah, blah, blah. No response, cannot have a body. view?
We misspelled method as method. Save that, go back and refresh the page, and make another edit. And there we go. data folder, and there is our document stored in a file named after its ID.
The content of that file, of course, is the actual document content. The last step in this process is retrieving the saved content from storage to set the editor content on page load. Let me quickly paste in another API endpoint to do this for us. ts.
It does just the opposite of the post request. That is, it reads the data from storage instead of writing it. Of course, just above we do the same checks as we did before, making sure document ID is passed correctly. Now back in the editor component, just after defining the component prompts, let's fetch the data from the API endpoint with Nuxt's useFetchComposable.
Then we'll await the result and extract the data as a variable called documentData. Then let's search the file for the variable called initialData. When we pasted this from the builder, it came with some boilerplate HTML, which is why we started with some content in the editor so far. And you can see it hard coded right here.
But now let's set this to the saved data from our KB storage. In the browser, all of our edits still persist. And in the file system, that is our permanent storage solution, the updates are reflected as well. At this point, we're no longer relying on the temporary storage from CK Editor, and I can open my docs days, weeks, or even months from now and still have the right content.