Build your first Blok editor
Mount Blok, capture some content, and save it as JSON you can store and load back — the full round-trip in five steps.
This is a hands-on walkthrough. By the end you'll have a working editor, you'll have saved its content to JSON, and you'll have loaded that JSON straight back in — the round-trip that everything else in Blok is built on.
Mount the editor
Point Blok at an element on your page and create an instance. Blok bundles no block tools, so register paragraph in the tools map — it is the tool the default block resolves to, and without it that first block renders a "This block cannot be displayed" stub instead of an editable line. Once isReady resolves you have a live editor with an empty paragraph waiting for the caret.
import { Blok } from '@bloklabs/core';
import { Paragraph } from '@bloklabs/core/tools';
const editor = new Blok({
holder: 'editor', // the id of a <div> on your page
tools: {
paragraph: Paragraph, // the default block every empty editor starts with
},
});
await editor.isReady;Write some content
Click in and type. Press Enter to start a new block, or press / to open the tool menu and choose a heading, list, or quote. Every line you create is a separate block.
Save it to JSON
Call save() to get your content as a plain object. There's no HTML to parse and no hidden state — just blocks you can store anywhere.
const data = await editor.save();
console.log(data);
// {
// time: 1719000000000,
// blocks: [
// { id: 'a1b2c3', type: 'paragraph', data: { text: 'Hello, Blok' } },
// ],
// version: '1.13.0', // the installed Blok package version
// }That object is the whole point. It's portable JSON you can drop into a database, a file, or an API — and it's exactly what you'll load back next.
Load it back
Hand the same object to render() and Blok rebuilds the content exactly. Save on unload, render on load — that's persistence, done.
// On the next page load, hand the same object back:
await editor.render(data);Add a tool
Blok ships lean — it registers no block tools of its own. Register the ones you want under the tools config and they appear in the / menu, ready to use. Keep paragraph in the map: there is no default set to fall back to, so every block type you rely on has to be listed, the default one included.
import { Blok } from '@bloklabs/core';
import { Header, List, Paragraph, Quote } from '@bloklabs/core/tools';
const editor = new Blok({
holder: 'editor',
tools: {
paragraph: Paragraph, // keep the default block registered
header: Header,
list: List,
quote: Quote,
},
});Checkpoint: what success looks like
You should now have a live editor on the page, a data object in hand from editor.save() with your blocks inside it, and that same object loading cleanly through editor.render(). If all three are true, you've got the round-trip — everything else in Blok builds on it.