Form Backend for Websites
SleekCMS includes a form backend built into the deployed site. Any <form> with a data-sleekcms="<name>" attribute is captured automatically — submissions stream into the CMS without a separate backend service, an action URL, or any JavaScript glue. No serverless functions, no webhook wiring, no third-party form service.
This page covers how form capture works in the deployed site, the markup contract, what's stored on each submission, and how the form-builder side of the CMS connects to the submissions inbox.
The Markup Contract
A form is captured if it has a data-sleekcms attribute set to a form name:
<form data-sleekcms="contact">
<label>
Name
<input name="name" type="text" required>
</label>
<label>
Email
<input name="email" type="email" required>
</label>
<label>
Message
<textarea name="message" rows="5"></textarea>
</label>
<button type="submit">Send</button>
</form>
Three things to know:
- The form name (
data-sleekcms="contact") groups submissions. Each unique name becomes a separate inbox in the CMS —contact,newsletter,quote-request,event-rsvp, whatever names you choose. - Field names (
name="email") become the keys on each submission. Use standard, descriptive names. - No
actionattribute is required. The site builder handles submission routing automatically. You can leaveactionoff entirely (the form submits to the same URL by default) and the SleekCMS sync layer intercepts the request.
That's the whole contract. Add the attribute, add named inputs, and submissions are captured.
How Submissions Are Captured
When a visitor submits the form on the deployed site, the SleekCMS forms backend:
- Receives the form POST.
- Validates the form name and basic field presence.
- Stores the submission against the form, indexed by submission time.
- Returns a success response (or an error if validation fails).
Submissions land in the CMS's Forms section, where you can review them, search across them, and export them.
Default vs. Custom Submission Pages
By default, after successful submission the user is shown a built-in success page provided by the SleekCMS forms backend. To customize the post-submit experience, add a hidden input named redirect with the URL to send users to:
<form data-sleekcms="contact">
<input type="hidden" name="redirect" value="/thank-you">
<!-- other fields -->
</form>
After a successful submission, the visitor is redirected to /thank-you. Use this to send users to a thank-you page you've built as a normal SleekCMS page.
Field Types and Storage
Any standard HTML form input is captured: <input> (all types), <textarea>, <select>, <input type="checkbox">, <input type="radio">, <input type="file">. The value is stored as it arrives on the server:
- Text-like fields → string values
- Checkboxes → present-or-absent
- Multi-select / multi-checkbox with the same name → array of values
- File uploads → stored against the submission, downloadable from the inbox
There's no schema declared for the form's fields on the SleekCMS side — the form is the schema. Adding a new input adds a new field to subsequent submissions. Removing an input from the HTML doesn't drop the field from past submissions; it just stops new ones from having that key.
Spam and Validation
The backend applies sensible defaults for spam protection:
- Honeypot field — Adding a hidden field named
_gotcha(or any name starting with_) catches naive bots that fill in every field. Submissions with the honeypot filled are silently dropped. - Rate limiting — Submissions are rate-limited per form per IP.
- Required field validation — HTML5
requiredattributes are enforced on the client side; the backend additionally validates that fields marked required have non-empty values.
For stronger spam protection, integrate Cloudflare Turnstile, reCAPTCHA, or hCaptcha as a hidden field on the form. The backend doesn't validate the challenge response itself — that's typically done via a publish trigger or a downstream system reading the submission inbox.
Booking Forms
A booking is just a form. Add an <input type="datetime-local"> to any data-sleekcms form and it becomes a booking form — at publish time that input is replaced by an availability slot picker, and submissions become appointments with email confirmation, calendar invites, and no-login cancel/reschedule links for the visitor. Every other field works exactly like a normal submission field and is stored with the booking.
<form data-sleekcms="consultation">
<input name="name" type="text" required placeholder="Your name">
<input name="email" type="email" required placeholder="Email">
<input name="slot" type="datetime-local" required>
<textarea name="notes" placeholder="Anything we should know?"></textarea>
<button type="submit">Book appointment</button>
</form>
Three rules:
- Include an email field (
type="email"orname="email") — the confirmation email and the manage links go there. - The datetime input's own
namedoesn't matter. The input is replaced by the slot picker, and the chosen time is stored as the booking's slot. - Style the form like any other. The slot picker inherits the page's
--accentCSS variable; setdata-accenton the form to override it.
Reusing the same form name across pages shares one booking form. Availability and appointments are managed in the CMS.
→ Bookings
Working with Submissions
Submissions appear in the SleekCMS sidebar under the Forms section, grouped by form name. From there you can:
- View the full submission with all fields.
- Search across submissions for a specific email, phone number, or text fragment.
- Export submissions to CSV.
- Delete submissions individually or in bulk.
Submissions are read-only — they're a record of what the visitor sent, captured at submit time. They cannot be edited from the inbox.
Access Control
By default, only admins see the Forms section. To grant access to editors, configure fine-grained access on the editor's membership and explicitly enable the Forms scope.
Two Sides of "Forms" in SleekCMS
There are two places "Forms" shows up in the CMS, and they serve different purposes:
| Where | What it's for |
|---|---|
/builder/forms (this page) |
The form authoring side — designing the form markup in your site code. |
/forms |
The submission inbox — viewing and managing what visitors have sent. |
The two are loosely coupled by the data-sleekcms form name. Renaming a form in your code effectively starts a new submission group; previous submissions stay attached to the old name.
A Practical Example
A newsletter signup that redirects to a thank-you page, has a honeypot, and uses Tailwind for styling:
<form data-sleekcms="newsletter" class="flex flex-col gap-3 max-w-md">
<input type="hidden" name="redirect" value="/newsletter/thanks">
<input type="text" name="_gotcha" class="hidden" tabindex="-1" autocomplete="off">
<label class="flex flex-col gap-1">
<span class="text-sm font-medium">Email</span>
<input
type="email"
name="email"
required
class="rounded-md border border-border px-3 py-2"
placeholder="[email protected]"
>
</label>
<button
type="submit"
class="rounded-md bg-accent text-white px-4 py-2 font-medium"
>
Subscribe
</button>
</form>
Submissions to this form land in the Forms section under newsletter. Each submission has an email field. Visitors who submit are redirected to /newsletter/thanks. Bots that fill the _gotcha field are dropped silently.
What's Next
- Form Submissions — The inbox side of the same feature.
- Site Members — Granting editors access to submissions.
- Automating using Triggers — Firing a trigger when new submissions arrive (e.g., to forward to email or a webhook).
- Assets and Static Files — Including CSS for form styling.