Forms & Form Builder
Create forms with the visual Form Builder and connect them to custom blocks using the `form` field type.
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:
- Form Builder (Dashboard > Forms) — define fields, validation, and actions
formfield 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:
| Property | Description |
|---|---|
| name | Unique field key (e.g. email, message) |
| type | text, email, textarea, number, phone, url, date, select, multiselect, checkbox, radio, file, hidden |
| label | Display label (multilingual) |
| placeholder | Placeholder text (multilingual) |
| validation | required, minLength, maxLength, minValue, maxValue, pattern, customMessage |
| width | full, half, or third — controls field width in the form grid |
| options | For select, multiselect, radio — array of { value, label } |
| order | Display order |
3. Configure Settings
| Setting | Description |
|---|---|
| Action Type | contact (email + save), newsletter (subscribe), login, register, custom (webhook) |
| Email Recipients | List of emails that receive form notifications |
| Webhook URL | For custom action — POST submission data to an external endpoint |
| Success Message | Shown after successful submission (multilingual) |
| Error Message | Shown on failure (multilingual) |
| Submit Button Label | Button text (multilingual) |
| Save Submissions | Store submissions in the database (default: true) |
| Send Email Notification | Email recipients on each submission (default: true) |
| Enable Captcha | Spam protection |
| Require Login | Only 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 typeThe 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:
| Block | Form Action | Description |
|---|---|---|
| Contact | contact | Contact form with info cards and quote |
| Newsletter Form | newsletter | Email signup form |
| Login Form | login | Authentication form |
| Register Form | register | User registration |
| Forgot Password Form | login | Password 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
- User submits form on the published site
- Server validates fields and checks rate limits
- Submission is saved with status
pending - Email notification sent to recipients (if enabled)
- Webhook called (if configured)
- 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
hiddenfield 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
halfandthirdwidths 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
webhookResponsefield for response details from your endpoint