optimistdigital/nova-page-manager
Built for Laravel Nova, this package lets you create, organize, and edit site pages with customizable templates, multilingual content, SEO fields, and slugs—all from the Nova admin panel. Includes block-based content editing, page structure control, and easy translation management.
Architecture fit. This is not a CMS — it is an editorial admin surface bolted onto Laravel Nova. It ships a Page/Region Nova resource, a config-declared template and block system, per-locale content, draft/publish state, and SEO fields, then deliberately stops: no routing, no rendering, no frontend. Content lands in your own MySQL tables as structured JSON and you render it through Blade partials you write. The TPM-relevant consequence is that any estimate must be split honestly: the package is roughly a day of integration; the actual deliverable is a block component library (one Blade partial per block type), a router, a preview route, SEO emission in the layout, and cache invalidation. Scope the second half or the "we just installed a CMS" narrative will blow up two sprints later.
Integration feasibility. Effectively gated on already running Laravel + a licensed Laravel Nova. If Nova is not in the stack, the real decision is a Nova purchase, not a page-manager evaluation, and that changes the TCO comparison against paid CMS options. Given Nova, feasibility is high and fast: composer require, vendor:publish, migrate, register two resources, declare one template and one region, ship one page end to end. That spike is one to two days and should be a scheduled gate before any roadmap commitment — it validates config → Nova editing → JSON → Blade in a single pass.
Technical risk. Ranked for a risk register:
hero_v2) and a migration command on rename.config:cache serializes them. If it breaks, it breaks in a deploy. Test in staging against pinned versions.outl1ne/nova-file-manager or spatie/laravel-medialibrary and store relative paths in block fields.Key questions to settle before greenlight. Who owns the Blade partial per block type, and is that person's time actually allocated? Which Nova major are we on, and what is the upgrade cadence commitment? Do editors need free-form page building — because if yes, this is the wrong tool and the constraint will surface as a defect report, not a design conversation. Which locales, and who produces translations? Do we need approval workflow beyond draft/published, and audit trail for content changes? What is the page-count and block-type trajectory over twelve months?
Stack fit. Laravel + Nova + MySQL/Postgres. The package slots in as a dependency, not an architectural centerpiece — provided you keep it that way. Put a thin application-owned repository in front of the model (PageRepository::findByPath()) so resolution, published-state filtering, locale fallback, and caching live in one class. The controller stays four lines and swapping the package later is a one-file change. Regions resolve through a view composer on the layout, cached separately from pages, scoped by locale.
Migration path. Three entry scenarios. From hardcoded Blade views: inventory the static pages, map each to a template, write php artisan pages:import against an export file — this is content work, not engineering work, and should be staffed and scheduled as such. From WordPress or another CMS: expect per-block mapping decisions and budget accordingly; the JSON shape is yours, so mapping is manual by nature. Greenfield: resist the full block kit. Launch one template with two blocks and one region, then add block types as roadmap items with a code-review gate. In all three cases, ship pages:export in the first week — it is simultaneously the backup and the exit plan, and its absence is what turns a fork into a fire drill.
Compatibility. Verify the package identity before debugging anything: the project moved from optimistdigital/nova-page-manager (OptimistDigital\PageManager) to outl1ne/nova-page-manager (Outl1ne\PageManager). Half the snippets online use the old namespace and produce class-not-found errors that read as a broken install. Pin one identity in composer.json, grep for stale imports, and confirm the installed major with composer show. Never edit vendor/ — subclass the Nova resource and override fields() for custom columns.
Sequencing. Four phases, days not a quarter:
Definition of done is not "installed." It is: preview works, cache invalidates on publish, every configured block has an asserted partial, and export runs.
Maintenance. Two upgrade streams treated as one — pin Nova and the package, read both changelogs before either moves, test against the Nova version in production rather than latest. Keep the block inventory test green; it is the cheapest guard against the silent-failure class. Keep pages:export current and versioned. Watch the package's release cadence as a leading indicator, not a guarantee: a recent release is a positive signal, but 179 stars and near-zero dependents means you are the support tier.
Support. Editor support load concentrates in three predictable tickets, and a pre-written runbook defuses all of them: "publishing didn't work" (cache not cleared — check the observer), "the page is 404" (it's a draft — check the published flag and raw JSON before touching routes), "the content disappeared" (a key was renamed — check git history on the config). Name an owner for the editorial queue and publish a one-page matrix answering "can I do this in the page manager, or does it need a developer?" That document is a product artifact, not an engineering one, and it is the difference between a self-service CMS and a ticket generator.
Scaling. Content volume is not the constraint — JSON in your own tables behind a cache layer scales fine for tens to low hundreds of pages. The constraints are editor throughput and block-type proliferation: every new block type is a code review and a deploy, so the block kit needs governance (who approves a new type, how many variants before the template set becomes a worse WordPress). Technically, watch translation N+1s when listing pages for menus or a sitemap — eager-load locales — and clear view cache when partials change, since content survives deploys but Blade templates do not.
Failure modes and mitigations. Maintainer abandonment → MIT fork, contained because content and rendering are yours. Nova major break → freeze the pair, do not upgrade independently. config:cache failure → caught in staging against pinned versions, with a fallback of moving template definitions into a service provider or registry resolved at runtime. Orphaned block keys → version keys, write a one-off migration on rename, or accept data loss knowingly and in writing.
Ramp-up. Developer ramp is one to two days with the spike as the onboarding artifact. Editor ramp is thirty to sixty minutes plus the block kit orientation. The larger ramp-up cost is organizational: the team must accept that content shapes are code-reviewed and deployed through the normal pipeline. That is the product constraint this package imposes, and it should be stated as a deliberate choice in the PRD — editorial freedom within an approved kit — rather than discovered by an editor who asks for a layout that requires a pull request.
How can I help you explore Laravel packages today?