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

Ux Vvvebjs Laravel Package

makraz/ux-vvvebjs

A Laravel package that integrates the VvvebJs drag-and-drop page builder, letting you create and edit HTML pages visually. It provides UX components and assets for quick setup and customization in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is a Symfony UX bundle, not a Laravel package. There is no service provider, no config/vvvebjs.php to publish, no Blade views, and no Laravel-facing form type. composer require makraz/ux-vvvebjs inside a Laravel app will pull Symfony Form/HttpKernel/Stimulus wiring you cannot boot. Treat v0.1.0 as a reference implementation and JS asset kit for VvvebJs, and lift the pieces you need.

Minimal path for a Laravel developer:

  1. Install the underlying editor directly — VvvebJs is framework-agnostic. Add its JS/CSS to resources/js and resources/css, or vendor the built assets into public/vendor/vvvebjs.
  2. Copy the bundle's Stimulus controller (assets/controller/…) into resources/js/controllers/. Stimulus works fine in Laravel via @hotwired/stimulus; register it in your app.js. This controller is the real value: iframe lifecycle, dynamic plugin/component loading, and hidden-field sync.
  3. Reproduce the form field as a Blade partial: a <div data-controller="vvvebjs" data-vvvebjs-…> plus <input type="hidden" name="content">.
  4. Reproduce the upload endpoint as a Laravel route + controller (POST /vvvebjs/upload) using Storage::disk(...) — Laravel's filesystem is Flysystem, so the "Flysystem backend" maps naturally to Storage::put.
  5. Store the resulting HTML in a longText/json column and render it through a sanitizer.

First useful use case: a pages.content HTML column edited by an admin through a full-width page builder, with a read-only preview for reviewers.

If you are on Symfony (or maintaining a hybrid), the bundle's own quick path is: enable the bundle, ensure symfony/stimulus-bundle ≥ 2.9.1, use VvvebJsType in a form, and optionally drop VvvebJsAdminField into EasyAdmin.

Implementation Patterns

Field + hidden input pattern. The bundle's core contract is simple and worth copying verbatim: render the editor into an iframe, keep the canonical HTML in a hidden input, sync on form submit and page unload. In Blade:

<div data-controller="vvvebjs"
     data-vvvebjs-height-value="700"
     data-vvvebjs-upload-url-value="{{ route('vvvebjs.upload') }}"
     data-vvvebjs-read-only-value="{{ $readOnly ? 'true' : 'false' }}">
  <input type="hidden" name="content" value="{{ old('content', $page->content) }}">
</div>

Multi-instance. The bundle supports several editors per page. In Laravel that means every instance needs distinct element IDs, its own hidden input name (blocks[0][html], blocks[1][html]), and a per-instance uploadUrl if uploads land in different folders. The Stimulus controller is scoped to its element, so this works — but plugin scripts loaded dynamically by VvvebJs can collide globally. Enable only the plugins each instance actually needs.

Uploads. Prefer a custom handler over the bundled backends. In Laravel terms: a VvvebJsUploadController with $request->validate(['file' => 'image|max:10240']), Storage::disk('public')->putFile(...), returning the JSON shape the editor expects. If you are literally porting the Symfony controller, keep its UploadHandlerInterface seam — it is the cleanest extension point in the package.

Self-hosting over CDN. Default assets come from jsDelivr. For any real app, set cdn_url equivalent to a local path and pin the VvvebJs version. Put the files under public/vendor/vvvebjs (or import through Vite) so CSP, offline dev, and asset versioning behave. The bundle supports both AssetMapper and Webpack Encore; the Laravel analogue is Vite — the same "just give me URLs" approach works.

Sanitize on write or read, always. Page-builder output is untrusted HTML by definition. Run it through mews/purifier (HTMLPurifier) before persisting or before rendering, and restrict designerMode to trusted roles. readOnly is a UI convenience, not a security boundary.

Admin panels. VvvebJsAdminField is the EasyAdmin one-liner. The Filament/Nova equivalents are a custom field wrapping the same Stimulus controller — expect ~50 lines, not a config flag.

Version pinning. It is 0.1.0 and explicitly pre-BC. If you vendor any of its code, fork it into your own repo with a comment pointing at the upstream commit, and don't track ^0.1.

Gotchas and Tips

  • Composer will mislead you. The package name and README look installable everywhere, but the runtime is Symfony Form + StimulusBundle + Symfony routing. In Laravel you get dependencies without integration. Budget for a port, not an install.
  • Sync only fires on submit and unload. Fetch/AJAX submissions, Livewire wire:submit, and Inertia visits may not trigger the unload sync reliably. In Livewire, bind the hidden input with wire:model and dispatch an input event from the controller after every editor change — don't rely on submit alone.
  • Livewire/DOM morphing will break the iframe. Re-rendering the component tears down the editor. Wrap it in wire:ignore and re-initialize the Stimulus controller on livewire:navigated.
  • Iframe isolation cuts both ways. Host-page CSS does not reach the canvas (good for fidelity, bad for "why doesn't my Tailwind look right"). Editor content needs its own stylesheet injected inside the iframe; VvvebJs component groups (BOOTSTRAP5, COMMON, etc.) assume their own CSS is present.
  • CSP and postMessage. The editor and host communicate across the iframe boundary. Restrictive frame-src/script-src policies will silently break syncing. Whitelist the CDN or self-hosted asset origin explicitly; check the iframe's console, not just the parent's.
  • Upload limits live in three places. The bundle's 10 MB default, PHP's upload_max_filesize/post_max_size, and Nginx's client_max_body_size. A "file too large" that never reaches your controller is usually the web server.
  • CSRF on the upload POST. The Symfony controller uses Symfony's token handling. A Laravel controller needs @csrf / X-CSRF-TOKEN wired into whatever the editor's uploader sends — the editor's default multipart request likely does not include it, so configure headers or exempt the route behind auth + throttle.
  • Flysystem "backend" is not Laravel's Storage facade. The bundle configures League Flysystem directly. In Laravel, skip it and write a custom UploadHandlerInterface-shaped class backed by Storage — you get disks, visibility, and URL generation for free.
  • Plugin and component-group selection is a payload decision. All six plugins and six groups are available, but each pulls scripts into the iframe dynamically. On slow connections the "dynamic loading of component scripts" is the first thing users notice. Ship the minimum set per form type.
  • Debugging checklist: (1) is the hidden input populated before submit? (2) do iframe console errors show 404s for plugin assets? (3) does cdn_url resolve under your CSP? (4) is the upload response shape what the editor expects (url, name, etc.)?
  • Extension points worth knowing: UploadHandlerInterface (custom storage), cdn_url (self-hosting), height/border (layout fit), designerMode/readOnly (role gating), and the plugin/component-group config (payload trimming). Everything else you will end up writing yourself.
  • Upgrade policy: experimental with no BC guarantee between releases. Pin exact versions, read the changelog on every bump, and assume the Stimulus controller's DOM contract may change.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle