⭐ Found this useful? Give it a star on GitHub! It helps us maintain and improve the project.
Visual Symfony page builder powered by GrapesJS, with Doctrine persistence, locale-aware content, CSRF-protected JSON document API, and Twig-based public rendering. Legacy section/column/widget documents (schema v1) remain supported for read/render.
Compatible with Symfony 7.4, 8.0, and 8.1+ on PHP 8.4+
This bundle is FrankenPHP worker mode friendly. Shared services stay request-safe; optional BuilderLocales static binding is cleared after each request. See FRANKENPHP-WORKER-AUDIT.md.
Public pricing — full demo context + Web Profiler |
Admin GrapesJS canvas — context + Web Profiler |
Page Builder Kit Bundle gives Symfony applications a reusable visual page builder backed by Doctrine. Editors create pages with stable keys, compose layouts on a GrapesJS canvas (or classic sections), save locale-specific content, publish or leave as draft, and expose pages on host routes or through Twig helpers. It complements Page Layout Kit Bundle when you need a free-form canvas instead of fixed typed blocks.
- GrapesJS admin canvas with preset-webpage + official plugins, Asset Manager, devices, a11y helpers, and PBK compound blocks
- Legacy schema v1 still supported (legacy): sections → columns → widgets (+ Sections editor). Prefer Grapes + content fields for new pages.
- Locale tabs /
localeContentwith default-locale fallback for public render - Configurable admin mount:
web_ui.path_prefix(default/admin/page-builder) - Optional
doctrine.table_prefixfor shared databases - JSON document API (GET/POST), publish / unpublish, public
/p/{pageKey} - Optional revisions history (
revisions.enabled) with restore, diff, templates, duplicate, import/export - Public edit pencil via
nowo_page_builder_can_edit()+ access checker; draft preview for editors - Sandboxed Twig in Grapes HTML; page SEO / Open Graph; asset uploads (local / S3)
- Dev Web Profiler panel (
debug.collector); classic widget packs for host extensions DocumentService,PageRenderProvider, Twignowo_page_builder_render()- Configurable access guard and HTML sanitization
- Symfony 8 FrankenPHP demo in
demo/symfony8(default port 8137)
composer require nowo-tech/page-builder-kit-bundle:^1.0
composer require twig/extra-bundle twig/string-extra# config/packages/nowo_page_builder_kit.yaml
nowo_page_builder_kit:
default_locale: es
locales: [es, en]
security:
access_roles: [ROLE_EDITOR]# config/routes/nowo_page_builder_kit.yaml
nowo_page_builder_kit:
resource: '@NowoPageBuilderKitBundle/Resources/config/routing.yaml'php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrateAdmin: /admin/page-builder/pages → open a page canvas.
| Topic | Page Layout Kit | Page Builder Kit |
|---|---|---|
| Mental model | Ordered list of typed blocks per configured page key | Tree document: sections, columns, widgets |
| Block / widget set | Fixed six types (hero, text, cards, …) |
Core six widgets; registry open to extensions (Phase 4) |
| Admin UX | Reorder list + inline CMS modals on public pages | Full-page canvas with drag-and-drop |
| Page keys | Declared in config (pages: [home, contact]) |
Created dynamically in admin (unique pageKey) |
| Content storage | One entity per block type + translations | Single JSON structure + per-locale widget props map |
| Public API | PageBlockProvider::getLayout() |
PageRenderProvider::getRenderedTree() / Twig nowo_page_builder_render() |
| Best for | Marketing pages with known block patterns | Landing pages and layouts that change shape often |
Use both bundles in one app when some routes need rigid blocks and others need a visual builder.
| Phase | Status | Scope |
|---|---|---|
| Phase 1–2 | Shipped (v1.0.0) | GrapesJS + classic v1, document API, publish/draft, i18n, SEO/a11y, security, demo |
| Phase 3 | Shipped (v1.1.0) | Revisions + diff, duplicate, import/export, templates library, draft preview |
| Phase 4 | Shipped baseline (v1.1.0) | WidgetPackInterface, author guide; classic widget tags |
| DX | Shipped (v1.1.0) | Web Profiler DataCollector (debug.collector) |
| Follow-ups | Shipped (v1.2.0) | Visual revision diff panels, template JSON sharing, Grapes block packs |
| Phase 5–7 | Shipped (v1.4.0) | Content fields + ACL capabilities, hardening/slots, media library + tags |
| Phase 9 | Done (v1.4.3) | Org compliance: ≥99% PHP elements, Symfony Form Twig (TWIG-003/005), README coverage |
Details: SPEC-DRIVEN-DEVELOPMENT.md. Spec Kit: specs/001–009 (docs closure in v1.1.1; follow-ups in v1.2.0; content/media in v1.4.0; polish + compliance in v1.4.1–v1.4.3).
make assets # pnpm + Vite: TS → src/Resources/public/
make -C demo/symfony8 assets # Pentatrion Vite: assets/app.ts → public/build/
make -C demo/symfony8 test-e2e
make -C demo/symfony8 demo-screenshots # refreshes docs/images/demo/*.pngmake up
make test
make phpstan
make -C demo/symfony8 up
make demo-smokeDemo default URL: http://localhost:8137.
- Architecture (Mermaid)
- Installation
- Configuration
- Widget authors
- Cookbook (packs + templates)
- PSR evaluation (REQ-CS-007)
- Usage
- Builder manual
- Contributing
- Code of Conduct
- Changelog
- Upgrading
- Release process
- Security
- Engram
- Spec-driven development
- GitHub Spec Kit
- GitHub Actions CI requirements
- Demo with FrankenPHP
- Use cases matrix
- Builder manual
- FrankenPHP worker mode audit
| Area | Status | Command |
|---|---|---|
PHP src/ coverage |
99.73% elements (CI gate ≥99%) | make test-coverage |
| TS/JS | N/A (canvas/typecheck only; no Vitest coverage suite yet) | pnpm typecheck |
| Python | N/A | — |
| Unit / bundle QA | Enabled | make test |
| Full release checks | Enabled | make release-check |
make test
make test-coverage
pnpm typecheck
make release-checkMIT — see LICENSE.


