Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Visual Editor Laravel Package

artisanpack-ui/visual-editor

A visual editor for Laravel that lets you build and edit page content directly in the browser, with a drag-and-drop interface that saves structured data your Blade views and models can render.

View on GitHub
Deep Wiki
Context7

Getting Started

This release (v1.15.2) is additive and bug-fix heavy — no breaking changes are called out — so the shortest path is: install, publish config/assets, point the editor at a model that stores block JSON (a blocks column or a dedicated blocks table), and render that JSON through the Blade renderer on the front end. Confirm the exact install command and entry point against the package README; the notes reference artisanpack/* block names and three renderers (Blade, React, Vue), which tells you the integration surface.

Where to look first, in order:

  1. The block registry / renderer contract. Every block in this release is rendered by all three renderers, so the registry is the map of what you get for free and what you'd have to extend.
  2. QueryInliner. It is the heart of dynamic content: it resolves Query loops on the front end and stamps _resolvedTotal, _resolvedItems, _resolvedCurrentPage, _resolvedPerPage, _resolvedTotalPages onto the block. Everything about Query Total, Query Pagination, Post Template, Post Reading Time and Related Posts flows through it.
  3. The breakpoint registry. Responsive attributes use mobile: / tablet: keywords, and the Navigation collapse point now references registry widths (767px / 1023px by default). Understanding this saves hours of "why did my nav collapse at 600px" debugging.

First use case: a CMS-backed "blog index" page — a Query loop with a Post Template grid, a Query Total above it, Query Pagination below it, and Post Reading Time inside each item. This exercises the newest blocks and the trickiest subsystem (query resolution) in one screen.

[
  { "name": "artisanpack/query-total", "attrs": { "displayType": "range-display" } },
  { "name": "core/query", "attrs": { "queryId": "blog-index" } },
  { "name": "artisanpack/query-pagination", "attrs": {} },
  { "name": "artisanpack/post-reading-time", "attrs": { "suffix": " min read" } }
]

(The above is illustrative of the attribute names this release documents, not a verbatim fixture.)

Implementation Patterns

Blade-first, React/Vue only where you need them. All three renderers are kept in parity, but the notes repeatedly call out blocks the React and Vue renderers don't render (artisanpack/form). If you're on Inertia, keep a Blade fallback path for those blocks rather than assuming parity.

Query loops as the primary dynamic pattern. The QueryInliner resolves loops on the front end and stamps _resolved* attributes. Build your own blocks or partials against those stamped values rather than re-running WP_Query-equivalent lookups — that's how Query Total, Query Pagination and Related Posts stay consistent. Each loop now pages on its own queryId query var, so multiple loops on one page (e.g. a sidebar "related" loop plus a main archive loop) no longer fight over pagination.

Compose blocks rather than custom-coding layouts. Post Template grids now collapse to two columns at ≤1023px and one at ≤767px, matching the Grid block. Related Posts now reads displayLayout (list or grid with columns) and Block spacing. If you were hand-rolling responsive grids in Blade partials, replace them with these blocks and let the renderer own the media queries.

Style through block supports, not custom CSS. Query Total, Image, Table, Post Featured Image and others carry typography, colour, spacing and border supports. Setting these in the editor keeps output portable across renderers; hardcoded CSS in your theme will diverge from the canvas preview.

Forms: lean on layout="inline". The Form block emits data-layout="inline" and an is-layout-inline class so your host form island and theme can put the submit button on the same row. Style against those hooks instead of reaching into the block internals.

Progressive enhancement for Social Share. The copy-link chip is a plain anchor by default and is upgraded to a clipboard button by the interactivity script, announcing results in a polite live region. Treat the anchor as the source of truth; don't build your own clipboard handler on top.

Cache deliberately. Because totals and pagination are resolved at render time, any full-page cache must key on the query vars each loop uses. Caching a Query Total page without varying on page number will serve "1–9 of 25" to everyone.

Navigation collapse as a design token. Set collapseBreakpoint to mobile or tablet rather than writing your own media query. The renderers emit <style data-ve-navigation-collapse> once per page with collapses-at-{key} on the <nav>; overriding it in your theme means fighting a page-level style tag.

Gotchas and Tips

  • defaultOpen needs a real boolean. An Accordion panel opens in Blade only for true; React and Vue match. A string "true" from loosely-typed JSON or a form post will silently stay closed.
  • Query Total renders nothing outside a resolved query. On the canvas it previews "25 results, 9 per page" as a placeholder; on the front end, if the surrounding Query didn't resolve, you get an empty string, not an error. If a block is mysteriously missing, check _resolved* first.
  • Empty collapseBreakpoint keeps the legacy 600px. 600px matches none of the registry widths, which is exactly the bug this attribute fixes. Set it explicitly on any nav in a wide header or you'll still overflow between 600px and 767px/1023px.
  • Saved query status is now dropped on the front end. If any internal tooling relied on a draft/private status persisting into front-end loop resolution, it won't. This is the intended security fix (cms-framework #403) — don't "restore" it with a filter.
  • Post Date format is finally honoured. It previously always printed F j, Y. Audit existing content where authors set a format and were unknowingly ignored; those pages will change appearance after upgrade. Carbon translatedFormat() is used server-side, with a PHP-format port in React/Vue — locale-sensitive formats may differ subtly between renderers.
  • Image width / height are strings now. "auto", "30px", "50%" print as inline style plus is-resized, matching the editor's save(). Legacy numeric values still render as attributes. If you were casting these to int in a custom renderer, stop.
  • Post Terms wraps every term. Unlinked terms (taxonomies without archives) were bare text nodes and are now elements. Selectors like .post-terms a will no longer match unlinked terms; use the wrapper element.
  • Query Pagination now prints nothing for a single page. An empty <nav> used to contain a lone "1". If you had CSS targeting that nav for spacing, it will now collapse entirely — use :empty checks or a wrapper.
  • Table now emits colspan, rowspan, scope and has-fixed-layout. Existing CSS with hardcoded table-layout: fixed may now double up with the block's fixed-layout class.
  • layout on Form accepts only stacked or inline. Any other value is dropped silently. Stacked output is unchanged, so no migration is needed for existing forms.
  • Breakpoint keywords vs arbitrary values. The renderers now re-emit competing breakpoint keywords after arbitrary rules so mobile:ap-basis-auto beats ap-basis-[280px]. This fixes a class of "my responsive override does nothing" bugs, but the specificity dance still exists — keep arbitrary values out of base declarations you intend to override responsively.
  • Flex panel wrap/alignment now wins over the layout baseline. If you had workarounds (custom CSS or !important) to undo .is-layout-flex { flex-wrap: wrap; align-items: center }, remove them; they'll now over-apply.
  • Related Posts and Post Template changed visually. Both now honour layout/spacing and responsive column collapse. Expect diffs on existing pages after upgrade — screenshot before and after.
  • Debugging checklist: confirm which renderer is active; inspect the DOM for data-ve-navigation-collapse, data-layout, collapses-at-*, is-resized and _resolved*; check whether the block is one of the Blade-only ones when debugging an Inertia page.
  • Extension points: the block registry and the renderer are the two seams worth learning. Registering a custom block gets you all three renderers' pipelines and the editor canvas for free; a custom QueryInliner hook is the place to adjust query vars if queryId-per-loop isn't granular enough for your setup.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings