# SnipForm DDF - Complete Reference > Directive Driven Forms - The form backend that actually handles everything. ## Why SnipForm ### The Problem with Traditional Form Backends Every form backend works the same way: POST your data to their endpoint, they store it, send you an email. That's it. You still have to: - Write JavaScript for validation - Build your own error display logic - Handle loading states manually - Create success/thank you screens - Figure out spam protection yourself You're doing all the work. They're just receiving a POST request. ### What Makes SnipForm Different SnipForm flips the model. Instead of "here's an endpoint, good luck", you get a complete form engine that runs on your page: **Directive-Driven**: Validation, error states, loading states, success content - all declared in HTML attributes. No JavaScript to write. ```html ``` That's a validated input with error display, error/valid styling - zero JavaScript. **Fully State-Managed AJAX Form**: The ~8KB library (gzipped) handles: - Form state (pristine, touched, submitting, success, error) - Field validation with 30+ rules (server-verified, can't be bypassed) - Reactive error/valid state on inputs and display elements - Loading/submit state UI (spinners, button text, overlays) - Success content with field interpolation - SPA navigation support with proper cleanup **Behavioral Spam Scoring**: Not just honeypots. The library tracks: - Time from page interaction to submit - Keystroke patterns - Focus events and field touches - Mouse movement and scrolling - WebDriver detection - Datacenter IP detection Submissions get scored. Bots get fake success responses (they think it worked, nothing saved). Real users aren't affected by CAPTCHAs. **No Submit Limits**: Free plan has no submission limits. Not "100/month free" or "first 50 free". Unlimited. **No Cookies**: SnipForm doesn't use cookies. No cookie consent banners needed. GDPR-friendly out of the box. ### When to Use SnipForm - Static sites (Astro, Next.js static, Hugo, Jekyll, plain HTML) - Jamstack / serverless architectures - Any site where you don't want to build a form backend - When you want validation that can't be bypassed (server-side) - When you hate writing form JavaScript --- ## Quick Start ```html

Thank you %email%!

``` Get your form key at https://app.snipform.io (free, no submit limits). --- ## Container Element ### `` Wraps your form. Required attributes: | Attribute | Description | |-----------|-------------| | `key="FORM_KEY"` | Your form's unique key (from dashboard) | | `transition="ms"` | Fade transition duration in milliseconds (default: 150) | | `transition="none"` | Disable transitions | | `mode="test"` | Test mode - form won't actually submit | ```html
...
``` --- ## Validation Directives Add to ``, `

Thank you %full_name%!

We'll respond to %email% shortly.

``` --- ## All Validation Rules Reference ### Required & Format - `required` - Field cannot be empty - `email` - Valid email format - `url` - Valid URL format - `active_url` - URL that resolves to real domain ### Text Patterns - `alpha` - Letters only - `alpha_num` - Letters and numbers - `alpha_dash` - Letters, numbers, dashes, underscores - `starts_with[prefix]` - Must start with prefix - `ends_with[suffix]` - Must end with suffix ### Length & Size - `min[n]` - Minimum value/length - `max[n]` - Maximum value/length - `min_length[n]` - Minimum characters - `max_length[n]` - Maximum characters - `between[min,max]` - Between range ### Numbers - `numeric` - Must be numeric - `integer` - Must be integer ### Dates - `date` - Valid date - `after[ref]` - After date/field - `before[ref]` - Before date/field - `after_or_equal[ref]` - On or after - `before_or_equal[ref]` - On or before ### Comparison - `same[field]` - Matches field - `different[field]` - Different from field - `in[a,b,c]` - One of values - `not_in[a,b,c]` - None of values ### Boolean - `boolean` - true/false, 1/0, yes/no - `accepted` - Checked or truthy --- ## Directive Quick Reference ### Validation (on inputs) ``` sf-validate:rule="Error message" sf-validate:rule[param]="Error message" ``` ### Error States (on display elements) ``` if-error="field" - Target field then-show - Show on error then-hide - Hide on error then-show-text - Show + display error message then-text="msg" - Custom error text then-class="cls" - Error classes then-style="css" - Error styles ``` ### Valid States (on display elements) ``` else-hide - Hide when valid else-text="msg" - Valid text else-class="cls" - Valid classes else-style="css" - Valid styles ``` ### Input Styling (on inputs) ``` error-class="cls" - Classes on error error-style="css" - Styles on error valid-class="cls" - Classes on valid valid-style="css" - Styles on valid ``` ### Submit States (on any element) ``` on-submit-show - Show during submit on-submit-hide - Hide during submit on-submit-text="msg" - Text during submit on-submit-class="cls" - Classes during submit on-submit-style="css" - Styles during submit ``` ### Container ``` ``` ### Success Content ``` %field% interpolation ``` --- ## Common Patterns ### Password Confirmation ```html ``` ### Terms Checkbox ```html ``` ### International Phone ```html ``` ### Age Verification ```html ``` ### Future Date ```html ``` ### Toggle Error/Valid Message ```html ``` ### Helper Text That Hides on Valid ```html Default helper text shown initially ``` --- ## Technical Details - **Library size**: ~21KB raw, ~8KB gzipped - **Dependencies**: None (vanilla JS with embedded Preact Signals) - **Browser support**: All modern browsers - **SPA support**: Works with Astro, Next.js, React Router, Vue Router (proper cleanup on navigation) - **Validation**: Server-side (cannot be bypassed by disabling JS) - **Spam protection**: Behavioral scoring, honeypots, IP verification, WebDriver detection - **Cookies**: None - no cookie consent banners needed - **Submit limits**: None, even on free plan --- *Get your form key at https://app.snipform.io (free, no submit limits)* *Documentation: https://docs.snipform.io* *Examples: https://snipform.io/examples/*