Docs › Saving and output
Saved HTML
What getHTML returns, phone-ready output and textarea sync.
When saving, read the post with editor.getHTML(). Editor-only markup is removed and the result is filtered through the allow-list. A few extras are added to images and tables so posts fit on phones.
Try it
Summer camping trip
The first photo loads at once; the second one loads when it comes close to the screen.
| Date | Place | Cost |
|---|---|---|
| Jul 12 | Gapyeong | $35 |
Code for this demo
createEditor('#editor', {
toolbar: 'heading | bold | link image table',
height: 320,
});What changes on the way out
- An empty editor returns
'', not an empty<p><br></p>. - Selection marks, uploads in progress, drag handles and other editing UI are removed.
- Images get
max-width: 100%; height: autoinstyle, pluswidth/heightfrom the natural size when they have neither. No overflow on phones, no layout jump while loading. - Tables are wrapped in
<div data-table-wrap style="overflow-x: auto">so they scroll sideways on narrow screens. The wrapper is taken off again when the post is loaded back. - Lazy loading: images after the first get
loading="lazy". The first is usually on screen right away. - With
linkRel, every http(s) link gets thatrel. See Links.
<h2>Summer camping trip</h2>
<p><img src="https://…/camp.jpg" alt="Campsite" width="640" height="360" style="max-width: 100%; height: auto"></p>
<p><img src="https://…/fire.jpg" alt="Campfire" width="640" height="360" style="max-width: 100%; height: auto" loading="lazy"></p>
<div data-table-wrap="" style="overflow-x: auto"><table>…</table></div>Turn these off with responsiveOutput: false and lazyImages: false. For the HTML exactly as edited, use editor.editHTML(); the source view and autosave drafts use it.
With a textarea
Pass a <textarea> to createEditor and its value is set to getHTML() on every change and right before the form submits, so the server reads the same field as before. See Textarea and forms.
Listening for changes
const editor = createEditor('#editor', {
onChange: (html) => preview.innerHTML = html,
});
// or
editor.on('change', (html) => { /* … */ });The change event fires once typing pauses, and only when the output HTML really changed. For plain text use getText(); for Markdown, getMarkdown() (Markdown).
Options
| Name | Type | Default | Description |
|---|---|---|---|
responsiveOutput | boolean | true | Images get max-width:100%; height:auto and natural width/height; tables get a sideways-scroll box |
lazyImages | boolean | true | loading="lazy" on images after the first |
linkRel | string | - | rel added to http(s) links; only nofollow, sponsored, ugc are taken |
onChange | (html) => void | - | Saved HTML on every change |
getHTML() | method | - | HTML to save; '' when empty |
editHTML() | method | - | HTML as edited, without the extras above |
getText() | method | - | Plain text with line breaks between blocks |
isEmpty() | method | - | True when there is no text, image, table or video |