Strapi Form Builder
Build, style, and embed forms anywhere with Strapi 5 — no backend code.
Introduction
Forms look simple until a project needs more than one of them.
At that point, teams start repeating the same work: defining content types for submissions, writing controllers, wiring validation, exposing endpoints, and building an editor so non-developers can actually manage fields. That work is necessary, but it's rarely the part that differentiates the product.
strapi-plugin-form-builder-cms was built to remove that repetition. Instead of rebuilding form infrastructure for every project, it gives Strapi teams a way to build forms visually, style them, publish them, and embed them on any website — while keeping full control over how form definitions and submissions fit into the rest of the application.
This article covers what the plugin does, why I built it, how it works under the hood, and where it's going next.
About This Plugin
strapi-plugin-form-builder-cms is a Strapi 5 plugin for creating, styling, and managing forms directly inside the CMS — and shipping them to any frontend with a single script tag.
At a high level, it lets you:
- Build forms with drag-and-drop in the Strapi admin — 16 field types, starter templates, and per-field validation
- Style forms visually with a live preview — colours, fonts, corners, layout — no CSS required
- Embed forms anywhere with one
<script>tag, or share a hosted public page - Protect against spam with a honeypot, per-IP rate limiting, Cloudflare Turnstile, and Google reCAPTCHA
- Manage submissions in an admin inbox with search, filters, bulk actions, and CSV export
- Stay headless — the form definition and submit endpoint are plain REST, so you can render forms yourself
That makes it useful for marketing sites, SaaS products, multi-page funnels, internal dashboards, and any project where forms are content, not just UI.
See it in action
Build → style → publish → embed, end to end in under a minute.
Why We Built It
The reason was practical, not theoretical.
In real Strapi projects, forms show up everywhere: contact pages, newsletter sections, request-a-demo flows, quotation pages, hiring pipelines, waitlists, support requests, onboarding. The first implementation is manageable. The third or fourth becomes expensive.
The repeated pattern looked like this:
- Create a content type for the form or its submissions.
- Decide how fields should be stored and validated.
- Build custom admin logic so non-developers can manage labels, placeholders, options, and required states.
- Build a frontend renderer, styling, spam protection, and a place to read submissions.
- Repeat the same architecture for the next form.
That repetition is exactly what a plugin should solve. Instead of rebuilding the same infrastructure per project, the plugin packages the entire form workflow — building, styling, embedding, and submission management — into one reusable Strapi extension.
How It Works Under the Hood
The plugin treats forms as structured CMS data, not isolated frontend widgets. A form becomes a manageable entity inside Strapi, with a draft and a published version.
1. Build visually, no code
The admin panel becomes a drag-and-drop builder. Add fields from a palette, reorder them on a canvas, and configure each one — label, placeholder, width, required state, and validation (min/max length, regex, email, URL, custom messages). Start blank or from a template (Contact, Newsletter, Feedback, Job application, Event RSVP).
2. Style it with a live preview
A dedicated Style editor themes the public form — accent colour, fonts, field styles, corners, spacing, card shadow, layout — with a live Desktop/Mobile preview. Everything resolves to a small set of --sfb-* CSS variables, and colour palettes are editable and saved with the form. The same resolved variables and stylesheet drive both the admin preview and the public embed, so there's no duplicated styling logic to keep in sync.
3. Draft and publish as snapshots
Both fields and styles are versioned. The public page, the embed, and the submit endpoint always read the last published snapshot — never the working draft. Saving a draft (fields or styles) never affects a live form; a publish overwrites the snapshot.
4. Embed anywhere — or stay fully headless
Publish a form and drop it onto any site with one script tag (zero dependencies, CORS handled by Strapi):
<div id="sfb-form-1"></div>
<script
src="https://your-cms.com/api/strapi-plugin-form-builder-cms/embed.js"
data-form-id="1"
async
></script>
The server serves a self-contained IIFE from GET /embed.js. On the host page it reads data-form-id, fetches the published schema cross-origin, and mounts the form — rendering fields, validation messages, honeypot, CAPTCHA widgets, and hidden-field prefill.
Prefer a link? Every form also gets a hosted public page. And if you'd rather render it yourself, the definition and submit endpoint are plain REST:
GET /api/strapi-plugin-form-builder-cms/forms/:slug/schema → the form definition
POST /api/strapi-plugin-form-builder-cms/forms/:slug/submit → a submission
So any frontend — Next.js, Astro, a React SPA — can fetch the schema and render inputs dynamically. Most teams reach for the one-line embed; the headless path is there when you need full control.
5. Security at the trust boundary
- CAPTCHA (Turnstile / reCAPTCHA v2) is verified server-side and fail-closed — an invalid, missing, or unreachable token rejects the submission, with a request timeout so a stalled provider can't hang the submit.
- The CAPTCHA secret key is stripped from the public schema — only the public site key reaches the browser.
- The post-submit redirect URL is validated to
http(s)/relative only, so ajavascript:/data:value can never execute. - Honeypot and per-IP hourly rate limiting run before persistence. Hidden tracking fields capture UTM parameters and referrers into each submission automatically.
Unit tests (Vitest) target those correctness and security paths; CI runs type-checks, the suite, a build, and a publish dry-run on every push.
What's Next (Roadmap)
The plugin already covers the full build → style → embed → manage loop. What's next is driven by real projects:
- Email notifications on new submissions
- Webhook integrations for CRMs, email platforms, and automation tools
- File upload field type
- Multi-step / wizard forms
- Version history and restore
- Deeper multilingual and multi-tenant support
How to Contribute
If you build with Strapi regularly and forms keep showing up in your projects, this plugin is worth trying. Install it, use it in a real workflow, and contribute feedback based on actual implementation experience. The most useful contributions are the most concrete:
- Bug reports with reproducible steps
- UX feedback from editors using the admin panel
- Proposals for missing field types or validation rules
- Frontend integration examples
- Pull requests that improve reliability or extensibility
Community plugins get better when they're shaped by real usage.