dewsign/nova-repeater-blocks
A Laravel Nova package that adds repeater block fields, letting you build flexible, repeatable content sections in your admin panel with a simple drag-and-drop style interface for managing structured data.
Architecture fit. The package implements repeaters as polymorphic Eloquent relations rather than as a serialized JSON column. Each "block" is a first-class model with its own table, attached to a parent model via a morphMany (or equivalent) relation. That is a genuine architectural commitment, not an implementation detail: it makes block content queryable, indexable, and relation-friendly, but it also means every block type requires a migration, a model, and a registration step in the field configuration. For teams whose content model is stable and whose blocks carry structured data you want to query or report on, this is the right shape. For teams that treat page content as an opaque document blob, it is strictly more work than a JSON-backed flexible-content field.
Integration feasibility. Feasible for a team already running Laravel Nova, but the package is a field-level UI component, not a content system. Expect to supply: block models, migrations, block-type registration, validation rules, delete/cascade semantics, and — critically — a front-end renderer, since nothing here dictates how blocks reach your application views or API. Realistic integration effort for a first block type end-to-end is a few days for a Nova-fluent developer; the long tail is content migration and lifecycle correctness, not the field itself. Note the hard prerequisite: Nova is a paid, licensed product, so this package is only usable inside an existing Nova installation.
Technical risk. Material, and concentrated in four places:
Key questions to resolve before committing:
Stack fit. The package targets the Laravel 8/9 + Nova 3/4 era. Confirm your PHP and Laravel versions against the package's composer constraints before anything else; a Laravel 10/11 application cannot assume compatibility. Because the package is admin-side only, it does not constrain your runtime stack — your API and front end read block models through ordinary Eloquent, which is a point in its favor.
Migration path. If you are moving from a JSON-column repeater (Nova's native field or a flexible-content package), plan a one-way, verifiable migration:
The reverse migration is significantly harder, so the bake period is not optional. If you are greenfield with no existing content, skip all of this and start from the block schema.
Compatibility. Pin the package version explicitly and lock it. The dominant breakage vector is a Nova major upgrade, which will silently invalidate the field's JS component while PHP tests still pass. Add a smoke test that mounts the field in a Nova resource and asserts it renders.
Sequencing.
Decision point after step 1: if the field does not render cleanly against your Nova version, stop. Forking a stale Nova field component is a real cost, and the fork should be a conscious, scoped decision rather than a rescue mission mid-project.
Maintenance. Assume you will own this code. Given the release history and adoption level, the realistic posture is: vendor the package into your repository (or fork it under your org) so you control patches, and budget a small recurring allowance — on the order of a day per Nova major upgrade — for compatibility work. If that allowance is unacceptable, do not adopt; a JSON-column repeater has near-zero maintenance cost by comparison and you should choose it deliberately rather than drift into it.
Support. Community-only. No vendor, no SLA, likely thin documentation. Internal onboarding material is a deliverable, not an afterthought. Name a single owner for the package inside the team.
Scaling. Two effects pull in opposite directions. Row count grows with content volume — a page with twenty blocks is twenty-plus rows and several joins, so a naive read path will produce N+1 queries on listing and API endpoints. Mitigate with eager loading of the morph relation and any nested relations, plus an index on the morph columns (blockable_type, blockable_id) and on the sort column. In exchange, you get queryability a JSON column cannot offer: reporting on block usage, cross-page queries by block field, and targeted updates without rewriting a whole document. For content-heavy sites the row-per-block model is generally fine at normal scale; it becomes a consideration only if you are rendering hundreds of blocks per request.
Failure modes to design against:
orderBy, block order can drift between reads — a subtle, hard-to-reproduce bug. Assert ordering in tests.Ramp-up. Low for a developer already comfortable with Nova and Eloquent; the polymorphic pattern is standard Laravel and needs maybe an hour of explanation plus the internal notes. Budget a half-day for a developer new to Nova. The real ramp-up cost is organizational: someone must own the fork, the upgrade allowance, and the block-type contract.
How can I help you explore Laravel packages today?