Content & editorial
Visual Page Builder
Indicative price, not an offer: EUR 200-400/year or EUR 500 one-off
Generated from docs/plan/paid/visual-page-builder/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
A visual drag-and-drop page builder plugin that allows non-technical merchants to create and customize campaign landing pages, product showcases, and homepage sections using pre-built blocks and templates, eliminating the need for developer involvement on routine content updates.
The problem
A merchant wants to launch a seasonal campaign or refresh their homepage layout but cannot hire a developer for each change. They spend weeks waiting for development resources or learning to code, while competitors deploy campaigns in days. They need a tool that lets them compose pages visually in minutes, not weeks.
What it does
- Drag-and-drop canvas editor for arranging pre-built page sections (hero, features, testimonials, grid, CTA, footer layouts)
- Component library of 20+ pre-styled block types (headline, text, image, button, product carousel, countdown timer, grid, testimonial card, accordion, form, spacer, divider)
- Inline block settings panel for customizing content, colors, fonts, spacing, sizing, alignment, and link targets without leaving the canvas
- Real-time visual preview of the page as the merchant edits; toggle between desktop and mobile (375px) viewport preview
- Page metadata editor (title, slug, SEO description, custom URL path, page name for internal reference)
- Publish/unpublish/save-as-draft workflow with confirmation modal and validation errors for incomplete sections
- Template system with 3+ pre-designed page templates (campaign landing, product showcase, testimonial wall) that merchants can clone and customize
- Version history with undo/redo during editing sessions (minimum 10-level undo stack)
- Live product data integration: product carousel blocks auto-fetch and display current products, prices, and inventory status
- Admin dashboard listing all pages with columns for name, slug, status (draft/published/archived), created date, last modified date, and quick-action buttons (preview, edit, duplicate, delete)
- REST API for programmatic page CRUD (create, read, update, delete, publish, duplicate, list with pagination)
- Audit trail integration: record page creates, publishes, and deletes with timestamp and user id
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Custom CSS or theme builder — core theming is out of scope; merchants cannot modify brand colors/fonts site-wide from page builder; global branding is a separate theming system.
- A/B testing, analytics, and performance reports — measurement belongs to a separate analytics module; page builder is for composition and publication, not testing.
- Scheduled publish/unpublish or timezone-aware scheduling — the core scheduler owns all time-based triggering; the builder is for immediate composition and publish actions only.
- Real-time multi-user collaboration (simultaneous editing) — concurrency control would require locking, conflict resolution, and WebSocket infrastructure; single-user editing only for MVP.
- Static asset hosting (uploading images/video directly in the builder) — assets must be uploaded to the core asset library first and referenced by ID; builder is a consumer of assets, not a host.
- HTML/code editor mode or importing designs from Figma/other page builders — these are migration tools; builder is design-native only.
Data model
New schema: Page entity with id (uuid), name, slug (unique, lowercase alphanumeric), title, description, sections (JSON blob containing tree of block objects), publishedAt (nullable timestamp), visibility (enum: draft | published | archived), createdAt, updatedAt, createdBy (user id). PageTemplate entity with id, name, sections (default block tree), createdAt. Each block object in sections: {type (string), id (uuid), props (object with type-specific content/styling), children (array of blocks)}. Block types include: hero, text, image, button, productCarousel, countdown, grid, testimonial, form, spacer. This IS a schema migration — new tables or collections required on all three drivers (lowdb, libSQL, relational).
API
- POST /api/pages
- GET /api/pages (with pagination: ?offset=0&limit=20, filters: ?status=draft)
- GET /api/pages/:id
- PUT /api/pages/:id
- PATCH /api/pages/:id/publish
- PATCH /api/pages/:id/unpublish
- POST /api/pages/:id/duplicate
- DELETE /api/pages/:id
- GET /api/pages/:slug/preview (public endpoint; 404 if unpublished)
- GET /api/admin/pages (admin list view with createdBy and audit fields)
- GET /api/admin/pages/templates
- POST /api/admin/pages/templates
- DELETE /api/admin/pages/templates/:id
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
New ‘Pages’ section in admin dashboard. List view: table showing name, slug, status badge (draft/published/archived), created date, last modified date, and action buttons (preview/new tab, edit, duplicate, delete). Edit view: visual canvas with component library sidebar (scrollable list of draggable blocks), canvas center (drag-and-drop area), settings panel right (properties for selected block), and preview toggle (desktop/mobile). Publish flow: modal with SEO fields (title, description), visibility dropdown, confirm button; validation errors block publish if required fields are missing. Template manager: list of built-in and custom templates, create template from current page, delete custom templates.
The seam — why this is paid
Core owns: page metadata (title, description, slug, SEO fields), URL routing (slug → page), REST framework, asset library (pages reference assets by ID), auth and permissions, audit log integration, page visibility and publishing state. Paid pack owns: visual page builder UI (React canvas, drag-and-drop library, block library component implementations, 20+ pre-styled block types), block settings panel UX, template presets (3+ designs), mobile preview toggle, undo/redo stack, builder admin page. Reason: the drag-and-drop editor with component library is a specialist SPA requiring ongoing UX support, design, and block maintenance. Core provides a generic REST API for pages (free); the merchant-facing visual editor is the paid value-add. No merchant is locked out of publication by payment (core API always available).
Paid specialist feature. Core provides basic templates; drag-and-drop page builder with component library requires support.
Dependencies
- Asset/file upload system (core feature) — pages reference uploaded assets by id; builder queries asset library
- Audit log (core feature) — to record page publish/create/delete events with user and timestamp
- REST framework and auth (core) — obvious dependency
- Plugin registration or admin panel extension API (core) — if builder admin is not bundled into core admin
- Assumption: Core provides page storage or this feature owns the Page schema
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- A page with 4 blocks (hero, text, productCarousel, cta) created in the builder saves to the database; GET /api/pages/:id returns all 4 blocks with correct type, props, and structure
- Publishing a page sets visibility=‘published’ and publishedAt to current timestamp; GET /api/pages/:slug/preview returns 200 with the page HTML/JSON; unpublishing sets visibility=‘draft’ and that endpoint returns 404
- An image block references an asset by id; if the asset is deleted from the asset library, the builder loads without crashing and shows a warning: ‘Asset missing’; storefront displays a placeholder image
- A productCarousel block fetches products from catalog API; when product price or name changes, published page reflects the update on next page load without re-editing the page
- A page previewed on mobile (375px viewport) displays responsive layout matching storefront rendering on actual iOS/Android device; elements reflow, font sizes adjust, images scale
- Creating a page from the ‘Campaign’ template completes in under 30 seconds and includes at least 4 pre-populated blocks; merchant can edit headline, add image, change CTA text, and publish in under 2 minutes without touching code
- Editing a page 10 times (add block, delete block, change text, resize, recolor, etc.) and clicking Undo 10 times returns the page to its pre-edit state; undo stack persists through a page refresh before publish
- User A and User B open the same page in the builder simultaneously; User A adds a block, saves, publishes; User B does not see the new block in real-time; User B must refresh to see User A’s published changes
- Attempting to publish a hero block with no headline text shows validation error ‘Hero section requires a headline’; publish button is disabled; error clears and button enables after adding headline
- Audit log contains records for each page publish event with exact timestamp (ISO 8601), user id of publisher, and page id; these records are queryable via GET /api/audit?resource=page&action=publish&limit=50
Risks
Schema migration complexity: adding Page and PageTemplate tables to all three drivers (lowdb JSON, libSQL doc-blob, relational SQL) without corrupting existing installs or missing migration in one driver. Asset reference integrity: deleting an asset that is referenced by published pages breaks those pages; need referential integrity checks or safe-deletion guards with warnings. Performance: pages with 50+ blocks or very large JSON sections may timeout on save; lowdb is especially vulnerable to large blob operations, hitting file-write limits. Security: block content (text, HTML) must be sanitized on input to prevent XSS; stored XSS would compromise the storefront. Dependency chain: if asset upload is broken, the entire feature is unusable (images cannot be added). UX perception: slow drag-and-drop or laggy preview creates negative perception of core product; must maintain responsive canvas performance. Backwards compatibility: changing block schema (renaming props, removing types) will silently break existing pages; need versioned block schema or graceful fallback for unknown props.
Commercial context
| Suggested price | EUR 200-400/year or EUR 500 one-off |
| Rival anchor | Magezon Page Builder (50+ elements, 100% CSS frontend) |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.