darvis/livewire-flux-editor-filemanager
A Livewire Flux editor file manager package for Laravel. Browse, upload, and manage files through a clean interface, and integrate file selection into Flux-powered editors. A simple way to add media handling to Livewire applications.
Confirm the stack before composer require. This package is not an editor — it is a composition layer over Flux Pro's flux:editor, and its image/file buttons are thin wrappers around Laravel Filemanager popups (?type=Images, ?type=Files) that depend on Filemanager's window.SetUrl callback. If you are not on Laravel + Livewire + Flux Pro, or you are not willing to adopt Filemanager's folder/permission/retention model, stop here. That is a platform decision, not an editor feature.
Three commands to a working install:
composer require darvis/livewire-flux-editor-filemanager
php artisan flux-filemanager:install
php artisan flux-filemanager:check
install publishes config/assets, patches the setup block in resources/js/app.js, and adds the table extension lines. check is the artifact you should trust — it reports missing wiring (including checklist_js_tables_enabled) and mirrors the in-app checklist page.
Read these four things, in this order:
resources/js/app.js — the flux:editor listener. Nearly every "button does nothing" bug lives here.flux-filemanager:check.config/flux-filemanager.php — disk, paths, upload limits, resize_presets, drag_drop.method, Filemanager route.lang/ — toolbar strings plus the 12 table-menu keys. Relevant the day you ship a non-English UI.First use case — prove the full round-trip before building anything else:
<flux:editor wire:model="content" />
Image button → Filemanager (?type=Images) → pick a file → window.SetUrl fires → <img src class="tiptap-image" width="400px"> lands in content. Single-click for resize/align, double-click for alt/title/width/classes/styles. Save, reload, confirm editor.getHTML() round-trips. That insert → style → save → reload loop is your smoke test for the entire integration.
The app.js contract you are now maintaining:
import * as fluxFilemanager from '../../vendor/darvis/livewire-flux-editor-filemanager/resources/js/laravel-filemanager.js';
import '../../vendor/darvis/livewire-flux-editor-filemanager/resources/css/tiptap-image.css';
document.addEventListener('flux:editor', (e) => {
e.detail.registerExtension(/* Image, extended */);
e.detail.registerExtension(/* Link, extended */);
['table', 'tableRow', 'tableHeader', 'tableCell'].forEach((n) => e.detail.enableExtension?.(n));
});
fluxFilemanager.initLaravelFilemanager(); // once, outside the listener
Treat app.js as a versioned interface. The namespace import (import * as fluxFilemanager) plus optional calls (createImageDropPastePlugin?.(), enableExtension?.()) is deliberate: if a vendored copy lags behind your setup block, one feature degrades gracefully instead of a module error taking out every toolbar button. Don't "tidy" it into named imports, don't drop the ?. — and note the contract in your upgrade runbook.
Tier editors by preset, not by branching code. Minimal (bold/link) for comments and internal notes; full for CMS and marketing surfaces (images, file links, tables, code blocks, HR, HTML source). Tables ship in full only. One codebase, several flux:editor configurations — but verifying each preset's extension set is your job now.
Pick an image strategy per surface and write it down. Set drag_drop.method = upload for anything persisted; the default base64 path is fine for prototypes but bloats the DB column and the HTML source. Decide once per editor, not per bug report.
Store HTML and treat everything touching it as round-trip risk. editor.getHTML() is the contract; the HTML source modal calls setContent() on the same string. Any sanitizer, importer, or API that mutates that string is now inside the round-trip path — test it.
Extend at the edges, not the core. Customize via resize_presets, published translations, and the package's views. If you need new editor behaviour, add a Flux command — never re-implement table-*, hr, or code-block; Flux's own toolbar handler owns those clicks and a second handler runs the command twice.
Use the debug ladder in team docs:
flux-filemanager:check → checklist page → app.js import/registration
→ browser console (extension names, explicit table message) → editor.getHTML()
That sequence resolves almost every "button does nothing" ticket without a debugging session.
Localization is a defined task, not a follow-up. Toolbar labels, table menu items, and checklist strings are all translation keys. Shipping full to a non-English market is a checklist item.
CI integration: wire php artisan flux-filemanager:check into your pipeline so a missing extension can't reach production as a silently disabled button.
Flux Pro 2.15.1 is a hard floor for tables. Below it, the table button renders disabled and the console explains why. Do the Flux bump in its own PR before touching this package — otherwise you're debugging two changes at once.
Never handle hr, code-block, or table-* in app.js. Flux runs setHorizontalRule, toggleCodeBlock, insertTable({ rows: 3, cols: 3, withHeaderRow: true }), addRowAfter(), mergeOrSplit(), deleteTable(). The package's JS only disables the table trigger when the editor has no table node. A second handler doubles every command.
The installer is a codemod. flux-filemanager:install edits your existing setup block. On heavily customized app.js files, expect duplicate lines or a failed patch: review the diff and let flux-filemanager:check arbitrate. If you never published the block, you have the easy path.
CSS loading is chained — don't break it. tiptap-table.css is imported by tiptap-image.css. Skip or override the image stylesheet and table styling silently disappears (cell paragraphs regain margins, header cells centre). Verify the table rules are scoped so they don't leak onto ordinary <table>s elsewhere in the app.
The HTML source modal drops unknown tags and attributes and lists the dropped ones under the textarea. Now that <table> is allowlisted, audit what actually survives — colspan, rowspan, style, class — and confirm it's safe on render. Add regression tests to any pipeline or snapshot that assumed tables were stripped.
Disabled button → console only. Fine for you, weak for content editors who won't open DevTools. If table authoring matters to the business, surface the missing-extension state in your own UI.
Livewire re-renders are already handled. The package delegates on document and keys off the closest ui-editor's editor property, so late-rendered editors work. If buttons die after a Livewire update, suspect that the element no longer resolves to an editor, or that extensions weren't re-registered on the new instance — not that the listener vanished.
Content-model caveats to decide up front. Tables ship with a <p> in every cell and require the full preset. Not covered by the release: cell backgrounds, column widths, row/column drag-reordering, cell alignment, and paste-from-Word/Sheets fidelity. If any of those are requirements, budget custom work.
Dependency risk is real but exit cost is low. 4 stars, 0 dependents, one maintainer: MIT, small surface, readable code. Adopt on a non-critical surface first, keep the vendored JS/CSS contract documented in-house, and never let it become the only thing between you and a release. Treat "are we willing to track Flux Pro releases?" as an explicit roadmap line item — the 2.15.1 floor is a de facto compatibility break inside a minor package release.
How can I help you explore Laravel packages today?