flowedit.
FLOWEDIT DOCUMENTATION

Editor guide

From the plugin documentation · View source ↗

FlowEdit replaces the plain Markdown textarea for page content in Admin2. This page documents the editing UI from an author’s perspective.

Toolbar

Above the canvas, left to right:

Button Action
Visual / Markdown Switches between the visual editor and editable Markdown source. Edits made in source mode are parsed back into the visual editor when you switch.
Outline Toggles a heading outline (H1–H3) sidebar; click a heading to jump to it. Open/closed state is remembered per browser.
Find Toggles the find & replace bar (see below).
Review Checks links, image alt text, and empty headings; click a finding to jump to it.
? Opens the keyboard shortcut cheatsheet (Lucide help icon).

Writing

  • Slash menu: type / at the start of a block to open the command menu (headings, lists, quote, code block, divider, table, columns, image, GIF, YouTube, gallery, video, embeds, and any enabled custom blocks). Recently used commands float to the top — this history is stored locally in your browser only.
  • Markdown typing: ordinary Markdown shortcuts still work (e.g. # for headings, - for lists, > for quotes, ``` for code fences).
  • Tables: insert a table from the slash menu; the bubble toolbar gains row and column actions (insert/remove) when the selection is inside a table. Pasted tab-separated text and HTML tables are converted into a table.
  • Columns: insert a two-column layout from the slash menu. With the caret inside a columns block, the bubble toolbar gains Lucide column actions (add/remove the current column, 2–4 total, and delete the whole block). Each column holds rich text, images, galleries, video, supported embeds, and structured custom blocks. Empty columns keep their position. On the front end, columns render side by side and stack on small screens.
  • Bubble toolbar: selecting text shows Lucide icons for bold, italic, strike, inline code, and link, plus text alignment (left / center / right / justify) applied to the current paragraph or heading. Alignment is stored as inline style="text-align:…" HTML in the Markdown and renders on the site as-is (no theme CSS needed). The link popover suggests internal pages (matched by title and route) and #anchors for the current page’s headings as you type. Selecting a whole block keeps the text-formatting bubble hidden; media, tables, and columns have their own contextual controls.
  • Paste/drop images: paste or drop an image directly onto the canvas to upload it to the page’s media and insert it in one step.

Keyboard shortcuts

Shortcut Action
/ Open the slash menu
Ctrl/⌘ + Alt + 1…3 Turn the current block into Heading 1–3
Ctrl/⌘ + F Open find
Ctrl/⌘ + H Open find & replace
Esc Close dialogs (slash menu, modals, cheatsheet)

The ? cheatsheet in the toolbar lists the same shortcuts.

Find & replace

The find bar supports plain-text search with optional case sensitivity, previous/next navigation, replace one, and replace all. In visual mode the search runs against the generated Markdown, so matches survive the visual ↔ source round trip.

Content review

The Review toolbar button opens an on-demand check of the whole document:

  • Links — broken internal links (verified against the site’s page routes), plain http:// links, and unsafe schemes like javascript:.
  • Images — images without alt text (both ![...](...) and [flow-image] blocks).
  • Headings — headings with no text.

Findings are grouped with colored severity dots (red = error, orange = warning, gray = info). Click a finding to jump straight to it in the editor. The toolbar button shows a badge with the number of errors and warnings from the last scan; use Re-check inside the panel after editing. If the page list cannot be loaded, internal links are skipped rather than flagged as broken. Fenced code blocks are never checked.

Media inserts (image / GIF / video)

  • Video upload: the video modal accepts a dropped/browsed MP4, WebM, or Ogg file — it uploads into the page’s media and fills the video source. Typed file URLs and Vimeo IDs work as before.

The image and GIF modals offer the same workflow:

  • Pick from the page’s media or the general (site) media, in collapsible lists.
  • Upload a local file, or paste an https:// image URL.
  • Alt text and an optional caption can be set at insert time.
  • Double-click an image on the canvas to replace it (same modal).
  • Draw crop on page media: drag resizable handles over the image, then Insert. This creates a new derivative file (named from the crop rectangle and source-file fingerprint) in the page folder — cropping never overwrites the original, and undoing the insert does not delete the derivative file. Next to the free Draw mode, the 1:1 / 4:3 / 16:9 presets constrain the rectangle to that aspect ratio while drawing and resizing.
  • Width (25–100%) and position (left / center / right) can be set via the bubble toolbar when an image, YouTube video, gallery, or video block is selected — the same align= value is stored in the shortcode. On the site, the plugin’s front-end CSS (css/flow-image.css, flow-gallery.css, flow-video.css) turns it into auto-margin placement.
  • Stock photos (image modal, when configured): search Pexels, Pixabay, or Unsplash and click a photo to download it into the page’s media.
  • Klipy GIFs (GIF modal, when configured): trending GIFs load as soon as the section is opened; search Klipy’s library and click a GIF to download it into the page’s media. Picking a GIF counts a share with Klipy per their attribution guidelines.

SVG files are excluded from the picker and upload control unless the administrator enables Allow SVG uploads; SVGs always render as <img src="…">, never inline.

When the administrator configures a stock provider (Pexels, Pixabay, or Unsplash), the image modal additionally offers a Stock photos section: search free stock photos, load more results, and click one to download it straight into the page’s media — it is inserted like any other page image (no hotlinking).

Structured blocks (custom blocks)

Custom blocks (callout, CTA, pull quote, accordion, tabs, table of contents, or types your site defines) are inserted from the slash menu. A modal form collects the block’s fields; the result is stored as a [flow-block] shortcode in the page body.

  • Use Edit on the block card, or double-click the card, to reopen its form.
  • Cards show the title and a readable, sanitized Markdown preview. The public appearance comes from your site’s Twig template.
  • Duplicate on the card inserts a copy of the whole block.
  • Save as snippet on the block card stores the filled-in block under a name you choose; it then appears in the slash menu under Saved (with a × to delete it) and inserts a ready-made copy anywhere. Saved snippets live in your browser’s local storage — use config snippets: for team-shared ones.
  • List-type blocks (accordion items, tabs) show a title + body repeater with add, remove, duplicate, and drag-to-reorder.
  • Blocks can be deleted like any other content; the surrounding text is not affected.

See the shortcode reference for the storage format and Creating custom blocks for the developer side.

Embeds

/embed (or simply pasting a supported URL onto an empty line) inserts a third-party embed: X/Twitter posts, GitHub Gists, Spotify tracks/albums/ playlists, and Google Maps. The URL is validated against an allow list — anything else is rejected with a hint. Double-click the embed card (or its Edit button) to change the URL.

Snippets & starter templates

Sites can define reusable snippets and page starter templates in the plugin configuration. Both appear in the slash menu (under Snippet / Starter) and insert their pre-written markdown at the cursor — including flow shortcodes, which become real editor blocks. Starters additionally pre-fill the editor automatically on the new page screen when their configured template matches.

Markdown source and draft recovery

The Markdown toggle shows the exact Markdown that will be saved — handy for checking what a structured block produced or for hand-tweaking content that has no visual equivalent. Switching back to Visual re-parses the source; any unsupported constructs may not survive a visual round trip unchanged.

Unsaved edits in both modes are backed up in this browser per page route. Reopening a page offers Restore or Discard when a different draft is available. A local draft is not a server save; use Admin2’s Save button.

If another writer changes the saved content, FlowEdit rejects your stale save and keeps your draft in the editor. Select draft Markdown selects it for copying. Reload saved content then Discard this draft and reload loads the current server content; copy anything you want to keep before confirming. Reconcile your copied changes and save again. This explicit reload also works when Sync has restored an older draft automatically.

The guard covers Markdown and blocks, including content saved from another Admin2 form tab after opening FlowEdit. It does not add conflict checks to title/settings-only saves or other editors. See the compatibility notes for scope and verification.

Legacy HTML blocks show a read-only preview with a warning. Their original HTML remains in Markdown source; replace them with a structured block using the legacy replacement steps.

Programmatic insertion

Other Admin2 plugins can insert content into the FlowEdit field by dispatching:

window.dispatchEvent(new CustomEvent('grav:editor:insert-content', {
  detail: { content: 'Inserted **Markdown**', mode: 'insert' }, // or 'replace'
}));

mode: 'replace' replaces the whole field value; omitting mode (or 'insert') inserts at the current caret position.