Use Case

    WYSIWYG Editor for Forms & Form Builders

    Replace plain textareas with rich text fields. Scribe's fixed toolbar, iframe isolation, isEmpty() validation, and XSS-safe HTML output make it the ideal WYSIWYG field for any form or form builder.

    Fixed
    Toolbar mode
    Iframe
    Style isolation
    isEmpty()
    Validation API

    Why Scribe works great in forms

    Replaces textarea inputs

    Drop Scribe onto any form field. Sync to a hidden input with onChange so the standard HTML form submit includes the formatted content.

    Iframe isolation mode

    Render the editor in an isolated iframe to prevent parent page styles from leaking in. Perfect for customizable form builders.

    isEmpty() for validation

    Check editor.isEmpty() before submission to prevent blank fields from being saved as empty HTML tags like <p></p>.

    Sanitized output for storage

    HTML from user form submissions is automatically stripped of XSS vectors. Safe to store directly in your database.

    HTML Form Integration

    Sync the editor to a hidden input so your form submits the HTML naturally — no changes to your existing form submission logic.

    import { Scribe } from 'scribejs-editor';
    import 'scribejs-editor/dist/scribe.css';
    
    // Replace a textarea with a rich text field
    const editor = Scribe.init('#description-editor', {
      toolbar:   'fixed',
      minHeight: 150,
      maxHeight: 400,
      placeholder: 'Enter a description...',
    });
    
    // Sync to hidden input so the form submits HTML
    const hiddenInput = document.querySelector('#description-value');
    editor.on('change', (html) => { hiddenInput.value = html; });
    
    // Validate and submit
    document.querySelector('#my-form').addEventListener('submit', (e) => {
      if (editor.isEmpty()) {
        e.preventDefault();
        document.querySelector('#error-msg').textContent = 'Description is required.';
        return;
      }
      hiddenInput.value = editor.getHTML();
    });

    React Hook Form / Formik

    A controlled component pattern that plugs into any React form library.

    import { useRef, useEffect } from 'react';
    import { Scribe } from 'scribejs-editor';
    
    // Controlled rich text field for React Hook Form / Formik
    export function RichTextField({ name, value, onChange, error }) {
      const containerRef = useRef(null);
      const editorRef    = useRef(null);
    
      useEffect(() => {
        editorRef.current = Scribe.init(containerRef.current, {
          toolbar:     'fixed',
          placeholder: 'Enter description...',
          onChange:    (html) => onChange(html),
        });
        if (value) editorRef.current.setHTML(value);
        return () => editorRef.current?.destroy();
      }, []);
    
      return (
        <div className="form-field">
          <label>Description</label>
          <div
            ref={containerRef}
            className={`rich-input ${error ? 'border-red-500' : 'border-gray-300'}`}
          />
          {error && <p className="error">{error}</p>}
        </div>
      );
    }
    
    // Usage with React Hook Form:
    // const { field } = useController({ name: 'description', control });
    // <RichTextField {...field} error={errors.description?.message} />

    Iframe Isolation Mode

    For form builders where each field must have its own isolated style context. The editor renders inside an iframe — parent CSS stays out, editor CSS stays in.

    import { Scribe } from 'scribejs-editor';
    
    // Iframe mode — editor renders inside an isolated iframe
    // Ideal for form builders with strict style isolation
    const editor = Scribe.init('#content-field', {
      mode:      'iframe',     // isolated from parent page styles
      toolbar:   'fixed',
      minHeight: 300,
      css:       '/editor-styles.css', // inject your own typography
      sanitize:  true,
      onChange:  (html) => {
        document.querySelector('#content-hidden').value = html;
      },
    });
    
    // Pre-fill with existing data (edit form)
    editor.setHTML(existingContent);

    Form editor features

    Fixed toolbar above the field
    Floating toolbar option
    Iframe mode for style isolation
    isEmpty() for required field validation
    getHTML() on submit
    setHTML() to pre-fill edit forms
    minHeight / maxHeight constraints
    Hidden input sync for native forms
    React Hook Form / Formik compatible
    Built-in XSS sanitization
    Paste-safe from Word & Google Docs
    MIT license — free to embed

    Upgrade every textarea in your form.

    Fixed toolbar, iframe isolation, validation API. The richest form field at the smallest bundle size.

    Form editor — common questions

    How do I add a WYSIWYG rich text editor to an HTML form?

    Initialize Scribe Editor on a div element inside your form. Add an onChange callback that writes the HTML to a hidden input field. When the form is submitted, the hidden input carries the formatted HTML content to your server. Use editor.isEmpty() to validate that the field is not empty before submission.

    Can Scribe Editor be used with React Hook Form or Formik?

    Yes. Create a controlled component that accepts value and onChange props. In the onChange callback from Scribe, call the form library's field onChange with the HTML string. Use useController (React Hook Form) or field props (Formik) to wire up the component.

    What is iframe editing mode in Scribe Editor?

    In iframe mode, Scribe renders the editable content inside an isolated iframe. This prevents parent page CSS from affecting the editor content, and prevents editor styles from leaking into the parent page. It is ideal for form builders, email template editors, and embedded editors in complex page layouts.

    How do I prevent empty rich text submissions in a form?

    Use editor.isEmpty() which returns true when the editor contains no meaningful content, even if it has empty HTML tags like <p></p> or <br>. Call this in your form submit handler and prevent submission if the field is required.