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#anchorsfor 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 likejavascript:. - 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.