outl1ne/nova-page-manager
A Laravel Nova package for creating and managing pages with flexible, block-based content. Build dynamic page layouts, edit SEO fields, and organize site content from a clean Nova interface, ideal for marketing sites, CMS-driven apps, and any project needing structured pages without a full CMS.
Architecture fit. This package is not a CMS; it is a pre-built Nova admin surface over two Eloquent concerns — slug-addressable pages and reusable, named regions — plus optional migrations and a default Blade view. That narrow scope is the point: it is an accelerator for teams already running Laravel Nova as their back office, and it substitutes for the hand-rolled page/region CRUD that would otherwise consume a sprint. Critically, it does not sit in the public request path unless we deliberately enable its catch-all /{slug} route. That keeps the blast radius of a wrong bet small and makes this a low-cost pilot rather than a platform commitment.
Integration feasibility. High, and cheap to prove. composer require, a vendor publish (per-tag if we expect to customize views), php artisan migrate, and resource registration in NovaServiceProvider is a sub-day developer spike. The package is thin enough to read end-to-end in roughly twenty minutes, which means "does it support X" questions get answered by source review rather than by vendor correspondence. The one non-trivial decision — whether the package or the application owns public routing — is a gate we should set explicitly before build, not discover later.
Technical risk. Manageable but concentrated in four areas:
published flag) is required before handing the tool to a non-technical team.Key questions to resolve before approval.
Page/Region models at the config layer, or accept the packaged models as-is?Stack fit. Hard requirement: Laravel + Laravel Nova. There is no path to reuse this outside a Nova back office, and that constraint should be stated in the decision record. Where the constraint holds, the fit is excellent — regions are first-class and shared, so a footer-cta or sidebar edited once and attached to many pages behaves like a curated block library rather than a bespoke page builder. That reuse is the real day-to-day editor win and the clearest justification over custom CRUD.
Migration path. Two distinct plays:
pages/content_blocks tables already exist, write a one-off mapping migration (slug/title/body → page + region rows), keep the legacy table read-only for one release as a rollback path, and cut over only when the renderer matches. Content is cheap to move early and expensive to move after editors have invested in the old tool.Compatibility. Pin the exact version and record the constraint matrix — Laravel, PHP, and Nova versions in the README — and add a CI job that installs against our pinned Nova version so a breaking Nova major fails in CI rather than in the editor's admin panel. Prefer the config-layer extension point (page_model / region_model bindings, keeping our models extending the package's) before considering a fork. Keep schema extensions additive in our own migrations; do not rewrite packaged migrations, which will collide on a future package update.
Sequencing.
published (and published_at if scheduling is in scope) plus a Nova toggle and resolver filter.Steps 1–3 are the pilot; 4–6 are the cost of making it production-safe; 7 is what prevents the tool's simplicity from becoming the thing that bites us.
Maintenance. Low steady-state, with one predictable spike: the annual Nova major. Decide the fork trigger now rather than under pressure — if package compatibility trails a Nova release by more than one cycle, vendor it into packages/ and own it. MIT licensing makes that cheap in principle; deciding reactively makes it expensive in practice. Assign a named owning engineer; a single-vendor package with this adoption level has no implicit maintainer.
Support. No vendor SLA. Support is entirely internal: one engineer accountable for upgrades, a short runbook covering install, model bindings, region-type mapping, and the config-cache gotcha, and explicit documentation of who publishes and how. Because there are no drafts or revisions, process documentation substitutes for tooling safeguards — it matters more here than on a mature CMS.
Scaling. The database is not the constraint; hundreds to low thousands of pages is comfortable. The plausible bottleneck is the Nova editor form with many regions per page — test with a realistic 20+ region page before committing, and if it is slow, split long pages across templates rather than adding fields per region. On the read path, eager-load pageRegions.region every time; N+1 queries here stay invisible until a page has twenty regions, then become the most common performance defect.
Failure modes to instrument.
@includeIf guard and a visible non-production placeholder naming the missing view.published flag is a prerequisite, not a nice-to-have./login or being shadowed by it → resolved by owning routing explicitly.Ramp-up. Asymmetric. A Laravel developer is productive in hours; editors need only brief Nova training. The real onboarding cost is process, not tooling — write down the publishing workflow before launch.
Success metrics for the pilot. Deploys avoided, content tickets closed without a developer, count of pages and distinct region types in use, frequency of draft/preview requests, and editorial complaints. Those numbers — not a feature matrix — are the inputs to the eventual headless CMS or DXP decision, and they justify deferring that procurement until content complexity actually demands it.
How can I help you explore Laravel packages today?