Slate's data model has been built with serialization in mind. Specifically, its text nodes are defined in a way that makes them easier to read at a glance, but also easy to serialize to common formats like HTML and Markdown.
And, because Slate uses plain JSON for its data, you can write serialization logic very easily.
For example, taking the value of an editor and returning plaintext:
Here we're taking the children nodes of an Editor as a nodes argument, and returning a plaintext representation where each top-level node is separated by a single \n new line character.
For an input of:
You'd end up with:
Notice how the quote block isn't distinguishable in any way, that's because we're talking about plaintext. But you can serialize the data to anything you want—it's just JSON after all.
For example, here's a similar serialize function for HTML:
This one is a bit more aware than the plaintext serializer above. It's actually recursive so that it can keep iterating deeper through a node's children until it gets to the leaf text nodes. And for each node it receives, it converts it to an HTML string.
It also takes a single node as input instead of an array, so if you passed in an editor like:
You'd receive back (line breaks added for legibility):
It's really that easy!
Another common use case in Slate is doing the reverse—deserializing. This is when you have some arbitrary input and want to convert it into a Slate-compatible JSON structure. For example, when someone pastes HTML into your editor and you want to ensure it gets parsed with the proper formatting for your editor.
Slate has a built-in helper for this: the slate-hyperscript package.
The most common way to use slate-hyperscript is for writing JSX documents, for example when writing tests. You might use it like so:
And the JSX feature of your compiler (Babel, TypeScript, etc.) would turn that input variable into:
This is great for test cases, or places where you want to be able to write a lot of Slate objects in a very readable form.
However! This doesn't help with deserialization.
But slate-hyperscript isn't only for JSX. It's just a way to build trees of Slate content. Which happens to be exactly what you want to do when you're deserializing something like HTML.
For example, here's a deserialize function for HTML:
It takes in an el HTML element object and returns a Slate fragment. So if you have an HTML string, you can parse and deserialize it like so:
With this input:
You'd end up with this output:
And just like the serializing function, you can extend it to fit your exact domain model's needs.