<smart-page-editor>

SmartPageEditor

A Notion-style block editor with rich block types, draft recovery, autosave, and full serialization API. Perfect for content management, blogs, wikis, and document editing applications.

Draft Recovery 14+ Blocks Autosave Notion-Style
<script src="https://cdn.jsdelivr.net/gh/Ketan-coder/smartelementsfiles@v2.0.4/page_editor.js"></script>

Basic Usage

The editor below shows all block types in action. Type "/" to access the command menu.

<smart-page-editor
  name="page_content"
  label="Page Content"
  placeholder="Start typing..."
  autosave-delay="1000"
  draft-recovery
  highlight
></smart-page-editor>

Supported Block Types

SmartPageEditor supports 14+ rich block types. Access any using "/" commands in the editor:

📝 Text & Headings
Paragraph, Heading 1/2/3 with automatic markdown shortcuts.
✅ Todo & Quote
Checklists with progress tracking and block quotes.
💻 Code
With Prism.js syntax highlighting (10+ languages).
🖼️ Media
Images, videos, audio with captions and alignment.
📊 Tables
Dynamic tables with add/remove rows and columns.
📐 Columns
Resizable 2-column layouts with drag divider.
🔗 Bookmark
Link preview cards via microlink.io (no API key).
➖ Divider
Visual horizontal separators between blocks.
💬 Callout
Highlighted alert/info blocks with icons.

Attributes

AttributeTypeDescriptionDefault
namestringForm field name for hidden input submissionpage
labelstringOptional label shown above editor
valuestringInitial content — JSON array or HTML string[]
placeholderstringText shown when editor is empty
requiredbooleanEditor must have content to validatefalse
required-messagestringCustom validation error messageContent is required
readonlybooleanRender-only mode, no editing allowedfalse
themestringColor scheme: auto, light, darkauto
styledstringStyle variant: default, bootstrapdefault
autosave-delaynumberDebounce ms for autosave (0 = disabled)1000
upload-urlstringServer endpoint for image uploads (POST multipart/form-data)
draft-recoverybooleanEnable localStorage draft autosave and crash recoveryfalse
highlightbooleanEnable Prism.js syntax highlighting (auto-loads from CDN)false

Events

Listen for content changes, saves, and dirty state updates.

EventDetailDescription
spe-change{ json, html }Fired on any content change (blocks modified)
spe-save{ json, html }Fired when autosave triggers (debounced)
spe-dirty{ dirty: boolean }Fired when unsaved state changes
const editor = document.querySelector('smart-page-editor');

editor.addEventListener('spe-change', (e) => {
  console.log('Blocks:', e.detail.json);
  console.log('HTML:', e.detail.html);
});

editor.addEventListener('spe-save', (e) => {
  console.log('Auto-saved', e.detail.json.length, 'blocks');
});

editor.addEventListener('spe-dirty', (e) => {
  document.querySelector('.save-btn').disabled = !e.detail.dirty;
});

JavaScript API

const editor = document.querySelector('smart-page-editor');

editor.getJSON();
editor.setJSON([{ type: 'heading1', content: 'Title' }]);
editor.getHTML();           // or exportHTML()
editor.getMarkdown();
editor.serialize();          // → JSON string (for Django TextField)
editor.deserialize(json);     // ← load from JSON string
editor.importHTML('<h1>Title</h1>');
editor.importMarkdown('# Title');
editor.clear();
editor.focus();
editor.undo();
editor.redo();
editor.validate();
editor.isDirty();
editor.markClean();
editor.clearDraft();

Django Integration

SmartPageEditor integrates seamlessly with Django forms and models.

In Your Template

<form method="POST">
  
  <smart-page-editor
    name="content"
    value=""
    required
    autosave-delay="1000"
    draft-recovery
    upload-url="/api/v1/upload-image/"
  ></smart-page-editor>
  <button type="submit">Save</button>
</form>

In Your View

def edit_page(request, pk):
    page = get_object_or_404(Page, pk=pk)
    if request.method == 'POST':
        page.content = request.POST.get('content')
        page.save()
        return redirect('page-detail', pk=page.id)
    return render(request, 'edit_page.html', {'instance': page})

In Your Model

class Page(models.Model):
    title   = models.CharField(max_length=200)
    content = models.TextField(default='[]')
    # OR: content = models.JSONField(default=list)