nyoncode/laravel-knowledge-base
A Laravel knowledge base for customers and internal teams: Diátaxis-styled articles, search-first navigation, revisions, reader feedback, a review freshness clock, and Livewire 3/4 components with publishable Blade views. Installs in three commands and mounts at /napoveda.
This package wires rich-text / editor fields into Livewire components so the editor's content is synchronised back to your component property. Start by installing it and checking the package's view/component stubs first — that is where the wire:model binding lives, and it is the thing most likely to bite you.
composer require <vendor>/<package>
Minimal first use case — a single editor field on a Livewire component:
<livewire:editor wire:model.live.blur="body" />
(or the package's own blade component/tag — check the README for the exact name).public string $body = '';
protected $rules = ['body' => 'required|string|max:20000'];
$this->validate(); Model::create(['body' => $this->body]);).Look first at: the package's published views (to see the actual binding expression), the README's Livewire section, and the test suite — the shipped tests encode the expected binding modifier and are the fastest way to confirm your environment matches.
Bind on blur, not on every keystroke. Editor content changes rapidly; sending an update per keystroke floods the server with large HTML payloads. The intended pattern is a blur (or change) sync, so the property updates when the user leaves the field, then a normal wire:submit or explicit $wire.set() handles the rest.
Draft + autosave. For long-form content, combine the blur binding with an explicit save action (wire:click="saveDraft") or a debounced listener, rather than trying to live-sync the editor body.
Multiple editors in one component. Give each editor its own property and its own binding; keep validation rules per-field so a failed validation only highlights the offending editor.
Integration with form objects. If you use Livewire form objects, bind the editor to wire:model.live.blur="form.body" — the modifier behaviour is identical, but remember validation messages resolve against the form object, not the component.
Testing your own usage. Assert the property is populated after a blur: use Livewire's ->set('body', '<p>hi</p>')->assertSet(...) for unit-level tests, and Dusk/browser tests when you actually need to prove the editor → server round-trip works in a real browser.
Upgrading to Livewire 4. If you copied the binding into your own Blade views (custom layouts, wrapped editors, slots), update those copies from bare wire:model.blur to wire:model.live.blur. The package's own views are fixed; your overrides are not.
wire:model.blur vs wire:model.live.blur is the whole ballgame under Livewire 4. Livewire 4 changed bare wire:model.blur / wire:model.change to be client-side only — the value updates in the browser but is never sent to the server unless you add .live. Symptom: the editor looks fine, the property is silently stale, and $this->validate() passes or fails against old content. If your editor "saves nothing" after a Livewire 4 upgrade, this is almost certainly it. Fix: wire:model.live.blur.
Custom/published views drift. If you published the package views to override markup, you will not get this fix automatically. Re-publish or diff against the vendor copy after every upgrade.
.live.blur still costs a round-trip. Very large documents mean a large request payload on blur; if you see slow saves, trim the editor's HTML (sanitise/strip on the server) or switch to a manual save button.
Sanitise server-side. The editor's HTML arrives over the wire as a plain string — treat it as untrusted. Run it through a HTML purifier before storage/rendering, regardless of what the editor UI allows.
Debugging a "not syncing" field. Check in this order: (1) the binding modifier in the rendered DOM (inspect the element, look for wire:model.live.blur), (2) that the property is public, (3) php artisan livewire:list / component name typos, (4) the browser console for JS errors in the editor's updated hook.
Extension points. The package's JS hook (typically an updated/x-data handler that pushes editor content into the model) is the place to hook custom toolbar behaviour or content normalisation. Keep customisations in your own JS layer rather than editing vendor files, otherwise the next patch release overwrites them.
Pin and test. This class of fix (a one-word binding modifier) is exactly the kind of change that silently breaks forms, so keep the package version constrained in composer.json and have at least one browser-level test that types into the editor, blurs, and asserts the server received the content.
How can I help you explore Laravel packages today?