Forms & Form Builder

Create forms with the visual Form Builder and connect them to custom blocks using the `form` field type.

Last updated: March 31, 2026

Overview

Cmssy has a built-in Form Builder that lets you create forms visually and connect them to any custom block. Forms handle validation, submissions, email notifications, and webhooks — so your blocks only need to render the UI.

The system has two parts:

  1. Form Builder (Dashboard > Forms) — define fields, validation, and actions
  2. form field type — connect a form to any custom block via its schema

Creating a Form

1. Open the Form Builder

Go to Dashboard → Forms → Create Form. Give it a name and slug (e.g. contact-form).

2. Add Fields

Each field has:

PropertyDescription
nameUnique field key (e.g. email, message)
typetext, email, textarea, number, phone, url, date, select, multiselect, checkbox, radio, file, hidden
labelDisplay label (multilingual)
placeholderPlaceholder text (multilingual)
validationrequired, minLength, maxLength, minValue, maxValue, pattern, customMessage
widthfull, half, or third — controls field width in the form grid
optionsFor select, multiselect, radio — array of { value, label }
orderDisplay order

3. Configure Settings

SettingDescription
Action Typecontact (email + save), newsletter (subscribe), login, register, custom (webhook)
Email RecipientsList of emails that receive form notifications
Webhook URLFor custom action — POST submission data to an external endpoint
Success MessageShown after successful submission (multilingual)
Error MessageShown on failure (multilingual)
Submit Button LabelButton text (multilingual)
Save SubmissionsStore submissions in the database (default: true)
Send Email NotificationEmail recipients on each submission (default: true)
Enable CaptchaSpam protection
Require LoginOnly logged-in users can submit

4. Publish

Set status to Published. Only published forms can be selected in blocks.

Using Forms in Custom Blocks

The form Field Type

To connect a form to your block, add a field with type: "form" in your block schema:

import { field } from "@cmssy/types";

export const schema = [
  field("formId", "form", {
    label: "Form",
    helperText: "Select a form from the Form Builder",
  }),
  field("submitLoadingText", "singleLine", {
    label: "Loading Text",
    defaultValue: "Sending...",
  }),
  field("successHeading", "singleLine", {
    label: "Success Heading",
    defaultValue: "Message Sent!",
  }),
];

In the editor, the form field renders a dropdown listing all published forms in the workspace. The selected form ID is stored in the block's content.

Rendering the Form

At runtime, use the form ID to fetch form data via the publicForm query and render the fields:

// In your block's React component
const { data } = useQuery(PUBLIC_FORM_QUERY, {
  variables: { workspaceSlug, formSlug },
});

const form = data?.publicForm;
// form.fields - array of field definitions
// form.settings - submit label, messages, action type

The form submission is handled by the submitForm mutation, which:

  • Validates fields server-side
  • Saves the submission (if enabled)
  • Sends email notifications (if configured)
  • Calls webhook (if configured)
  • Returns success/error response

Built-in Blocks with Forms

Cmssy ships several blocks that use the form system:

BlockForm ActionDescription
ContactcontactContact form with info cards and quote
Newsletter FormnewsletterEmail signup form
Login FormloginAuthentication form
Register FormregisterUser registration
Forgot Password FormloginPassword reset request

These blocks use formId in their schema — you can inspect them as reference implementations.

Form Submissions

Viewing Submissions

Go to Dashboard → Forms → [Your Form] → Submissions. Each submission shows:

  • All field values
  • Status (pending, processed, spam, archived)
  • IP address, user agent, referrer
  • Timestamp
  • Email/webhook delivery status

Submission Lifecycle

  1. User submits form on the published site
  2. Server validates fields and checks rate limits
  3. Submission is saved with status pending
  4. Email notification sent to recipients (if enabled)
  5. Webhook called (if configured)
  6. Status updated to processed

Spam Protection

Forms include built-in rate limiting:

  • Per-IP rate limit per form
  • Optional captcha support
  • Honeypot fields can be added as hidden field type

Action Types Reference

contact

Saves submission + sends email to configured recipients. The default for most forms.

newsletter

Subscribes the email field to the workspace newsletter list.

login / register

Handles authentication. These are special action types used by the built-in auth blocks.

custom

POSTs the submission data as JSON to your webhook URL. Useful for integrating with external services (Zapier, Slack, CRMs, etc.).

Tips

  • Always publish your form before selecting it in a block — draft forms won't appear in the dropdown
  • Use half and third widths to create multi-column form layouts (e.g. first name + last name side by side)
  • Multilingual labels — form fields support per-language labels and placeholders, matching the site's language system
  • Test submissions are saved like real ones — delete them from the Submissions tab when done
  • Webhook debugging — check the submission's webhookResponse field for response details from your endpoint
Forms & Form Builder — Cmssy Docs | Cmssy