Alpine Editor Docs

Get Started › Inline Editor

The inline editor

Instead of replacing a <textarea> with a boxed editor, inline mode turns content you already have on the page — a <div>, an <article>, any element — into the editable surface itself, in place. No menu bar, no fixed toolbar, no status bar. It's the mode you want for CMS-style "click to edit this section" pages.

1. Mark up the content you want editable

Unlike the boxed themes, inline mode doesn't start from a hidden <textarea> — the element's existing HTML is the initial content. Give it a hook to select on:

<div data-inline>
  <h2>Welcome</h2>
  <p>This paragraph is a live inline editor.</p>
</div>

Any element works — <div>, <article>, <section> — as long as it's not a <textarea>, which can only ever hold plain text.

2. Initialize with inline: true

Same AlpineEditor.init() call as any other mode, just with inline: true and selector pointing at the element(s) from step 1:

document.addEventListener('alpine-editor:ready', () => {
  AlpineEditor.init({
    selector: '[data-inline]',
    inline: true,
  });
});
Note: as with any embed, wait for alpine-editor:ready before calling init() — see Get started. theme and height are ignored when inline is set.

3. How it behaves

There's no chrome to click into — the element itself responds to hover and focus:

StateWhat happens
HoverA light outline previews that the element is editable.
Focus (click in)The outline turns solid and a floating toolbar appears, left-aligned to the element — above it by default, or below if there isn't room above.
Blur (click away)The outline and toolbar disappear. Clicking into a toolbar control (e.g. a color picker) doesn't count as blurring.

Everything else — typing, undo/redo (Ctrl/Cmd+Z), links (Ctrl/Cmd+K), find & replace (Ctrl/Cmd+F), tables — works exactly like the boxed themes. The one exception is fullscreen: there's no container to expand, so Ctrl/Cmd+Shift+F has no effect in inline mode.

4. Multiple editable regions

selector can match more than one element — each becomes its own independent inline editor instance, exactly like a CMS wiring up several separately editable regions on one page:

<div class="page">
  <div data-inline><h2>Welcome</h2><p>First block.</p></div>
  <div data-inline><p>A second, independent block.</p></div>
</div>

<script>
  AlpineEditor.init({ selector: '[data-inline]', inline: true }).then((editors) => {
    console.log(editors.length); // 2
  });
</script>

5. The toolbar

With no menu bar to fall back on, inline mode's default toolbar is a richer, two-row set that covers fonts and colors directly:

// inline mode's default toolbar — two rows
[
  'undo redo | bold italic underline | fontfamily fontsize',
  'forecolor backcolor | alignleft aligncenter alignright | bullist numlist | outdent indent',
]

Override it the same way as any theme, with a single string or an array of strings for multiple rows — see the full token reference in Themes & Toolbar.

AlpineEditor.init({
  selector: '[data-inline]',
  inline: true,
  toolbar: 'bold italic | link',
});

6. Reading and saving content

getContent(), setContent() and onChange all work exactly like the boxed themes — full reference in Content & Events. The one difference: a boxed editor mirrors its content back onto a hidden <textarea>.value on every change; inline mode skips that step, since the element you selected already is the content.

const [editor] = await AlpineEditor.init({ selector: '[data-inline]', inline: true });

document.getElementById('save').addEventListener('click', () => {
  fetch('/api/sections/1', {
    method: 'PUT',
    body: JSON.stringify({ html: editor.getContent() }),
  });
});

7. Tearing down

editor.destroy() removes the floating toolbar and turns off contentEditable — unlike the boxed themes, the element isn't hidden or replaced, its current content just stays on the page, no longer editable:

editor.destroy();
Note: a tracked session also ends automatically when the tab closes or the page is hidden, so you don't need to call destroy() just to stop being counted against your usage.

Full example

<div class="page">
  <div data-inline>
    <h2>Welcome</h2>
    <p>Hover this block to see it's editable, click in for the toolbar.</p>
  </div>
</div>

<script src="https://your-app.test/embed/YOUR_TOKEN.js"></script>
<script>
  document.addEventListener('alpine-editor:ready', () => {
    AlpineEditor.init({
      selector: '[data-inline]',
      inline: true,
      onChange: (editor) => console.log(editor.getContent()),
    });
  });
</script>

Where to go next