Title: HXFE — Code-First Forms
Author: youheiokubo
Published: <strong>June 10, 2026</strong>
Last modified: June 10, 2026

---

Search plugins

![](https://ps.w.org/hxfe-code-first-forms/assets/banner-772x250.png?rev=3567567)

![](https://ps.w.org/hxfe-code-first-forms/assets/icon-256x256.png?rev=3567567)

# HXFE — Code-First Forms

 By [youheiokubo](https://profiles.wordpress.org/youheiokubo/)

[Download](https://downloads.wordpress.org/plugin/hxfe-code-first-forms.1.3.7.zip)

 * [Details](https://wordpress.org/plugins/hxfe-code-first-forms/#description)
 * [Reviews](https://wordpress.org/plugins/hxfe-code-first-forms/#reviews)
 *  [Installation](https://wordpress.org/plugins/hxfe-code-first-forms/#installation)
 * [Development](https://wordpress.org/plugins/hxfe-code-first-forms/#developers)

 [Support](https://wordpress.org/support/plugin/hxfe-code-first-forms/)

## Description

**HXFE — Code-First Forms** is a code-first WordPress form plugin. Instead of building
forms in a GUI, you define them as PHP arrays and place a shortcode anywhere.

This means your forms live in your codebase — version-controlled with Git, automatically
deployed, and free from database migration issues.

#### Why code-first?

 * **Git history for free** — Every change to your form shows up in `git diff`
 * **Deploy without fear** — Forms are code, so they deploy with your theme. No 
   more “the form disappeared on production”
 * **Dynamic options** — Pull select options from `get_posts()`, taxonomies, or 
   any PHP source. No manual updates
 * **One schema, four UIs** — Add `step_mode: chatbot` or `one_by_one` to transform
   the same fields into a completely different interface

#### Four UI modes from one schema

 * **Normal form** — Classic input  confirm  complete flow (default)
 * **Step form** — Multi-page with progress bar (`steps` array)
 * **One-by-one** — Question-at-a-time survey style (`step_mode: 'one_by_one'`)
 * **Chatbot** — Chat bubble interface with typing animation, header, and timestamps(`
   step_mode: 'chatbot'`)

#### Key features

 * 15 field types: text, email, tel, url, textarea, select, radio, checkbox, checkbox_group,
   number, date, file, honeypot, reCAPTCHA, privacy
 * Conditional logic: show_if, required_if, skip_if (hide_if deprecated) — works
   in chatbot mode too
 * Dynamic routing: to_rules, subject_rules, complete_redirect_rules, complete_html_rules
   based on submitted values
 * Diagnosis mode: use `complete_html_rules` without `to` — show results without
   sending email
 * Download after submit: `download_url` shows a download button on the complete
   screen (document request forms)
 * Form availability window: `available_from` / `available_until` with custom before/
   after HTML
 * Custom validation: `pattern`, `minlength`, `maxlength`, `error_message` schema
   keys + `hxfe_validate_field` and `hxfe_validate_form` filter hooks
 * Field HTML injection: `before_html` / `after_html` schema keys
 * Page slug tracking: subject auto-appended with `[form-id@page-slug]` for per-
   page aggregation
 * Webhook support: send to Zapier, Make, Slack, or any HTTP endpoint
 * SMTP built-in: Gmail, SendGrid, Mailgun, or custom SMTP
 * File upload: attached to email, auto-deleted after send
 * IP restriction and password-protected forms
 * iframe embedding with per-form CORS control (`allowed_origins`)
 * Zero cookies: GDPR/EU cookie-compliant by design
 * Clean default styles: CSS custom properties (design tokens) for easy theme integration,
   responsive at 768px
 * Schema examples panel in admin: 11 copy-paste samples to get started fast
 * AI-friendly: ships with `llms.txt` and `ai-reference.md` for agentic coding tools

#### Minimum example

    ```
    add_filter( 'hxfe_schemas', function( $schemas ) {
        $schemas['contact'] = [
            'id'      => 'contact',
            'to'      => 'admin@example.com',
            'subject' => 'Contact: {name}',
            'fields'  => [
                [ 'key' => 'name',  'type' => 'text',     'label' => 'Name',    'required' => true ],
                [ 'key' => 'email', 'type' => 'email',    'label' => 'Email',   'required' => true ],
                [ 'key' => 'body',  'type' => 'textarea', 'label' => 'Message', 'required' => true ],
                [ 'key' => 'hp',    'type' => 'honeypot' ],
            ],
        ];
        return $schemas;
    } );
    ```

Shortcode: `[hxfe_form id="contact"]`

#### Chatbot example

    ```
    $schemas['support'] = [
        'id'        => 'support',
        'to'        => 'admin@example.com',
        'step_mode' => 'chatbot',
        'bot_name'  => 'Support Bot',
        'bot_icon'  => '🤖',
        'greeting'  => 'Hi! How can I help you today?',
        'fields'    => [
            [ 'key' => 'name',  'type' => 'text',  'label' => 'Name',
              'bot_message' => 'What is your name?' ],
            [ 'key' => 'email', 'type' => 'email', 'label' => 'Email',
              'bot_message' => 'Thanks {name}! What is your email?' ],
            [ 'key' => 'hp', 'type' => 'honeypot' ],
        ],
    ];
    ```

#### Diagnosis chatbot (no email)

    ```
    $schemas['diagnosis'] = [
        'id'        => 'diagnosis',
        // No 'to' — result shown without sending email
        'step_mode' => 'chatbot',
        'complete_html_rules' => [
            [ 'when' => ['plan', '==', 'basic'],
              'html' => '<h3>Basic plan recommended</h3><p>Hi {name}!</p>' ],
            [ 'when' => 'default',
              'html' => '<p>Thank you, {name}. We will be in touch.</p>' ],
        ],
        'fields' => [ ... ],
    ];
    ```

#### Organize schemas in separate files

    ```
    // functions.php — one line
    require_once get_template_directory() . '/inc/hxfe-forms.php';
    ```

Or use HXFE as a standalone plugin with `glob()` auto-loading.

### External Services

This plugin optionally connects to Google reCAPTCHA when the `recaptcha` field type
is enabled in a form schema.

**What the service is and what it is used for:**
 Google reCAPTCHA is a spam-prevention
service. When enabled, it loads a script from Google’s servers and verifies the 
user’s response server-side to determine whether the form submission is from a human
or a bot.

**What data is sent and when:**
 When a page containing an HXFE form with reCAPTCHA
is loaded, the visitor’s browser loads the reCAPTCHA script from `google.com`. On
form submission, the reCAPTCHA token generated in the visitor’s browser is sent 
to Google’s verification endpoint (`https://www.google.com/recaptcha/api/siteverify`)
along with your site key. No other form field data is transmitted to Google.

reCAPTCHA is **disabled by default**. It is only active when a site administrator
adds a `recaptcha` field to a form schema and configures valid API keys in the plugin
settings.

**Links:**
 * Google reCAPTCHA Terms of Service: https://policies.google.com/terms*
Google Privacy Policy: https://policies.google.com/privacy

## Installation

 1. Upload the plugin folder to `/wp-content/plugins/`
 2. Activate in **Plugins  Installed Plugins**
 3. Add schemas via the `hxfe_schemas` filter in `functions.php`
 4. Place `[hxfe_form id="your-id"]` in any page or post
 5. View all registered forms at **Settings  Form Engine — Forms**

## FAQ

### Does HXFE save submissions to the database?

No. HXFE sends email only. This is intentional — forms defined in code stay lightweight
and free of database dependencies. Use Webhook support to send data to external 
services like Google Sheets or a CRM.

### Can I use HXFE without writing PHP?

HXFE is designed for developers who want code-first form management. If you need
a GUI builder, plugins like WPForms or Fluent Forms may be a better fit.

### Does the chatbot mode work with conditional logic?

Yes. `show_if` conditions work in chatbot mode — hidden fields are automatically
skipped. You can also use `{field_key}` placeholders in `bot_message` to reference
previous answers.

### Is HXFE GDPR / EU cookie compliant?

Yes. HXFE uses zero cookies. Form state is preserved via hidden JSON fields on the
server side, not browser storage.

### Can I embed forms on external domains?

Yes. Use `[hxfe_iframe id="contact" site="https://your-site.com"]` and configure
allowed origins in **Settings  Form Engine  iframe / CORS Settings**.

### How do I connect to Zapier or Make?

Add a `webhooks` array to your schema with the target URL. HXFE will POST form data
as JSON after each successful submission. Webhook failures do not block form submission.

### Can I skip the confirmation screen?

Yes. Add `'confirm' => false` to your schema. Works for normal forms and step forms.

### Can I restrict a form to specific IP addresses?

Yes. Add `allowed_ips` to your schema with a list of IPs or CIDR ranges. Visitors
outside the whitelist see a blocked message, which you can customize with `ip_blocked_html`.

    ```
    allowed_ips => [ '192.168.1.0/24', '203.0.113.5' ],
    ip_blocked_html => '<p>This form is only available on the campus network.</p>',
    ```

### Can I require a password to access a form?

Yes. Add an `auth` key to your schema. To keep passwords out of Git, define them
as constants in `wp-config.php` and reference them in the schema.

In `wp-config.php`: `define( 'HXFE_STAFF_PASS', 'your-secret-password' );`

In your schema:
 ‘auth’ => [ ‘users’ => [ [ ‘id’ => ‘staff’, ‘password’ => defined(‘
HXFE_STAFF_PASS’) ? HXFE_STAFF_PASS : ” ] ] ]

Brute-force protection is built in — access is locked for 15 minutes after 5 failed
attempts.

### Can I prevent PHP files from being edited via the WordPress admin?

Yes. Add this to `wp-config.php`:

    ```
    define( 'DISALLOW_FILE_EDIT', true );
    ```

This disables the theme and plugin editors in the WordPress admin. It pairs well
with HXFE’s code-first approach — forms and code are managed via deployment, not
the admin UI.

### Can I save uploaded files somewhere other than email attachments?

HXFE deletes uploaded files from the server immediately after sending the email.
This is intentional — keeping files on the server increases security risk and GDPR
responsibility.

For permanent storage, the recommended approach is to use Gmail + Google Apps Script(
GAS): set up a time-based trigger that reads incoming form emails and saves attachments
to a designated Google Drive folder. This keeps files off your WordPress server 
entirely and lets you manage access through Google’s permission system.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“HXFE — Code-First Forms” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ youheiokubo ](https://profiles.wordpress.org/youheiokubo/)

[Translate “HXFE — Code-First Forms” into your language.](https://translate.wordpress.org/projects/wp-plugins/hxfe-code-first-forms)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/hxfe-code-first-forms/),
check out the [SVN repository](https://plugins.svn.wordpress.org/hxfe-code-first-forms/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/hxfe-code-first-forms/)
by [RSS](https://plugins.trac.wordpress.org/log/hxfe-code-first-forms/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.3.7

 * Security: Removed skip_sanitize parameter from hxfe_process_fields() — all values
   are now sanitized on every call, including confirmsubmit flow
 * Security: Clarified that sanitize_text_field() and related functions are idempotent,
   so re-sanitizing already-sanitized values is safe

#### 1.3.6

 * Security: Added nonce verification to hxfe_handle_back() to prevent unauthorized
   form re-rendering
 * Security: Back button now passes hxfe_nonce (hxfe_validate_{form_id}) via hx-
   vals
 * Code: Clarified skip_sanitize=true comment in hxfe_handle_submit() to explain
   double-sanitize prevention

#### 1.3.5

 * Renamed schema key: `redirect_rules`  `complete_redirect_rules` (consistent with
   other `complete_*` keys)
 * Renamed schema keys: `before_open_html` / `after_close_html`  `before_html` /`
   after_html`
 * Renamed field keys: `min_check` / `max_check`  `min` / `max` (consistent with`
   min_date` / `max_date`)
 * Deprecated field key `hide_if` — use `show_if` instead (backward compatible, 
   will be removed in a future version)

#### 1.3.4

 * Added: Page slug auto-injected into subject as [form-id@slug] for per-page tracking
 * Added: Schema examples panel in admin UI with 7 copy-paste samples
 * Added: Responsive breakpoint at 768px
 * Added: CSS custom properties (design tokens) for easy theme customization
 * Added: `download_url` / `download_label` schema keys — download button on complete
   screen
 * Added: `available_from` / `available_until` schema keys — form availability window
 * Added: `before_html` / `after_html` schema keys — custom messages outside window
 * Added: `allowed_origins` schema key — per-form iframe CORS restriction
 * Added: Embed HTML `<iframe>` copy button in admin form list
 * Improved: Admin UI redesigned — stat cards, clean table, monospace field type
   chips
 * Improved: chatbot send button replaced with paper-plane SVG icon
 * Improved: Login/auth screen with border, padding, full-width button
 * Improved: iframe / CORS Settings tab removed — now schema-level only
 * Fixed: hx-encoding=”multipart/form-data” auto-applied when file field present
 * Fixed: File name shown correctly on confirm screen
 * Fixed: File attachment preserved through confirm  submit flow
 * Fixed: Temporary file cleanup cron (hourly, 1h expiry)
 * Fixed: Fade-in flash bug (remove+reflow caused visible flicker)
 * Added: `complete_html_rules` schema key — conditional complete screen HTML (supports{
   field_key} interpolation)
 * Added: Diagnosis/calculator mode — omit `to` with `complete_html_rules` for no-
   email chatbot
 * Added: chatbot + `show_if` / `required_if` conditional fields now fully supported
 * Improved: chatbot UI redesigned with LINE/Slack-style header, timestamps, and
   bubble shadows
 * Added: `pattern` / `minlength` / `maxlength` / `error_message` schema keys for
   field-level validation
 * Added: `hxfe_validate_field` filter for per-field custom validation
 * Added: `hxfe_validate_form` filter for cross-field validation (password confirm,
   at-least-one, etc.)
 * Added: `before_html` / `after_html` schema keys for injecting HTML around fields
 * Added: `disable_context` schema key to opt out of page slug auto-injection

#### 1.3.3

 * Renamed: SHFE  HXFE across all PHP/JS/CSS (class names, IDs, function prefixes)
 * Fixed: Scroll after htmx outerHTML swap (re-fetch element by ID after swap)
 * Fixed: Step form Back button returning 403 (nonce was missing from hx-vals)
 * Fixed: chatbot phpcs:ignore comment appearing as visible text in UI
 * Fixed: Copy button fallback for HTTP environments (execCommand)
 * Changed: Shortcode copy buttons labeled “Form” / “iFrame” for clarity

#### 1.3.2

 * Added: IP restriction — whitelist IPs and CIDR ranges per form (`allowed_ips`)
 * Added: Customizable IP blocked message (`ip_blocked_html`)
 * Added: Form-level password authentication (`auth.users`)
 * Added: Brute-force protection — lockout after 5 failed attempts (15 min)
 * Added: Auth session via secure httponly samesite=strict cookie
 * Added: Login form labels fully customizable per form
 * Added: Support for wp-config.php constants as password source (keeps secrets 
   out of Git)

#### 1.3.1

 * Security: file field now uses HXFE’s own safe MIME whitelist by default instead
   of WordPress defaults
 * Security: added .htaccess to hxfe-uploads/ directory to prevent PHP execution
 * Added: file field type now works — uploaded files are attached to admin notification
   emails
 * Added: includes/file-upload.php with wp_handle_upload() based processing
 * Added: mime_types schema key to whitelist allowed MIME types server-side
 * Added: temporary files are automatically deleted after email is sent
 * Removed: lint warning about file field being unimplemented

#### 1.3.0

 * Refactored: extracted field renderer functions to includes/fields/field-renderers.
   php
 * Refactored: added hxfe_validate_step_request() to DRY up step endpoint gate logic
 * Refactored: improved PhpDoc type definitions on core functions (hxfe_process_fields,
   hxfe_eval_condition, hxfe_interpolate)

#### 1.2.2

 * Fixed: confirm_label now correctly applies to the input form submit button
 * Fixed: hxfe-front.js (scroll, focus, loading state) was not enqueued
 * Fixed: disable_default_css and custom_css now work correctly
 * Fixed: chatbot.js is now only loaded on pages with chatbot forms
 * Fixed: uninstall.php now removes all plugin settings from the database
 * Added: error_message schema key to customize the validation error summary text
 * Added: confirm_label schema key (separate from submit_label for clarity)
 * Note: file field type renders HTML but file saving is not yet implemented

#### 1.2.1

 * Added tel and url field types with built-in validation
 * Added Webhook support (Zapier, Make, Slack, custom HTTP endpoints)
 * Added label customization: submit_label, back_label, next_label, confirm_heading
 * Fixed confirmation screen: radio/select now shows label instead of value
 * Fixed confirmation screen: checkbox_group shows comma-separated labels
 * Fixed confirmation screen: hidden fields (show_if=false) are now excluded
 * Fixed mail body: empty fields and hidden fields are now excluded
 * Added confirm: false support for step forms
 * Added built-in placeholders: {site_name}, {site_url}, {date}, {time}
 * Added admin form list page with lint warnings and shortcode copy buttons
 * Strengthened schema lint: all 15 field types, cascade_from, chatbot bot_message
 * Added wp_mail() failure logging when WP_DEBUG is enabled

#### 1.2.0

 * Added field types: radio, checkbox_group, number, date, file
 * Added chatbot UI mode (step_mode: chatbot) with typing animation
 * Added 4 completion patterns: message, custom HTML, redirect, redirect_rules
 * Added default values (value key on any field)
 * Added multiple recipients (to as array)
 * Added confirm: false for immediate submission
 * Added cascade select (cascade_from / cascade_options)

#### 1.1.0

 * Added step forms (groups and one_by_one mode)
 * Added reCAPTCHA v2 and v3
 * Added privacy policy field
 * Added auto-reply email
 * Added SMTP configuration (Gmail, SendGrid, Mailgun, custom)
 * Added iframe embedding with CORS support
 * Added conditional logic (show_if, required_if, skip_if, to_rules, subject_rules)
 * Added CSS customization options

#### 1.0.0

 * Initial release
 * Schema-driven form rendering
 * htmx-powered input  confirm  complete flow
 * Admin notification email and auto-reply
 * Honeypot spam protection

## Meta

 *  Version **1.3.7**
 *  Last updated **6 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.0 or higher **
 *  Tested up to **7.0**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [chatbot](https://wordpress.org/plugins/tags/chatbot/)[contact form](https://wordpress.org/plugins/tags/contact-form/)
   [form builder](https://wordpress.org/plugins/tags/form-builder/)[htmx](https://wordpress.org/plugins/tags/htmx/)
 *  [Advanced View](https://wordpress.org/plugins/hxfe-code-first-forms/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/hxfe-code-first-forms/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/hxfe-code-first-forms/reviews/)

## Contributors

 *   [ youheiokubo ](https://profiles.wordpress.org/youheiokubo/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/hxfe-code-first-forms/)