Phase 1 + 2 + 3 — MVP → partner hardening → scale
Embeddable conversion core: design a campaign, embed it anywhere, turn submissions into classified inquiries.
One portable campaign JSON is the contract between Studio, the Campaign Service, and the Loader — so the same campaign renders in the OneHub app today and on a partner site in Phase 2 without a rewrite.
✓
Studio (builder)
GrapesJS + OneHub tokens
✓
Campaign Service
Next.js route handlers + store
✓
Loader SDK
Vanilla TS, Shadow DOM, 9.4 KB
✓
Lead pipeline
submission → inquiry → ingest
✓
Analytics
PostHog events (view/interact/submit)
✓
Multi-tenancy
per-partner keys + origin allowlist
✓
A/B + dashboards
sticky variants, per-partner self-serve
The core loop
- 1Marketer builds a form / popup in Studio (GrapesJS) — no engineer.
- 2Publish → an immutable campaign version is frozen server-side.
- 3Loader fetches it and renders inside an isolated Shadow DOM.
- 4Visitor submits → /api/submit stores it and fires form_submit.
- 5Pipeline normalizes it into an inquiry and ingests it (classified + tagged to workspace).
- 6view / interact / submit land in PostHog → conversion baseline.
Current configuration
- Storage
- Postgres
- Analytics (PostHog)
- no-op (console)
- Inquiry pipeline
- no-op (stored + logged)
- Campaign schema
- v0 (portable JSON)
- Loader isolation
- Shadow DOM (+ iframe fallback)
- Cross-origin
- per-partner key + origin allowlist
- Campaign types
- inline · modal · slide-in · sticky
- Experiments
- A/B variants (sticky, per-visitor)
All integrations are optional in Phase 1. With nothing configured the app runs on a local file store and logs analytics/inquiries to the console — copy .env.example to .env.local to wire the real services.