WP Manifestindependent plugin directory
manifest / forms / bluefairy-forms

BlueFairy Forms

BlueFairy Forms — Zero-asset-bloat WordPress forms plugin with libsodium encryption at rest (Pro)

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/bluefairydevelopment/bluefairy-forms/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Zero-asset-bloat WordPress forms plugin. Build forms with a Gutenberg block or shortcode, with GDPR-safe submissions and built-in spam protection — no jQuery, no bloat.

Requirements

  • WordPress 6.4+
  • PHP 8.1+

Installation

# From the WP plugins directory:
composer install --no-dev
wp plugin activate bluefairy-forms --path=/path/to/wordpress

Usage

Gutenberg Block

Add the BlueFairy Form block to any page or post, then enter the form ID in the Inspector Controls panel.

Shortcode

[bluefairy_form id="1"]

WP-CLI

wp bluefairy-forms list-forms
wp bluefairy-forms doctor

Creating Forms

Go to Tools > BlueFairy Forms > Add New. Define your form as JSON:

{
  "schema_version": "1.0",
  "submit_label": "Send Message",
  "success_message": "Thank you! Your message has been sent.",
  "fields": [
    { "id": "name",    "type": "text",     "label": "Your Name",      "required": true },
    { "id": "email",   "type": "email",    "label": "Email Address",  "required": true },
    { "id": "message", "type": "textarea", "label": "Message",        "required": true }
  ]
}

Supported field types

text, email, tel, url, textarea, select, radio, checkbox, number, date

Spam Protection

BlueFairy Forms includes a built-in honeypot field and timetrap token. For stronger protection (Stop Forum Spam lookup, shared block log), install the free BlueFairy Anti-Spam plugin — the two plugins detect each other automatically with no configuration needed.

GDPR

IP addresses are HMAC-hashed before storage using a site-specific key generated on activation. Raw IPs are never stored. Submission data is exportable and erasable via WordPress's built-in Privacy tools.

Anti-Spam Integration Hooks

Other plugins can hook into the spam-check system:

// Render spam fields for a custom form:
do_action( 'bluefairy_antispam_render_fields', 'my_form_type' );

// Check a submission for spam:
$is_spam = apply_filters( 'bluefairy_antispam_check', false, $_POST, 'my_form_type', $ip, $email );

Page caches (1.1.9)

A page that shows a form is sent uncacheable (DONOTCACHEPAGE and nocache_headers()), and the form fetches a fresh nonce and time token on load from GET /wp-json/bffrm/v1/tokens/{form_id} (never cached; 30 requests a minute per address). A time token more than a day old asks the visitor to send again (bffrm_error=expired); it is not treated as spam. Every refused submission is recorded with its reason (no field values) and listed under Refused submissions on the Submissions screen.

Extension Hooks

// Add or change fields before a submission is stored:
add_filter( 'bffrm_submission_payload', fn( array $payload, int $form_id, array $form ) => $payload, 10, 3 );

// Settings an add-on adds to Tools > BF Forms — Settings (rows inside the form table):
add_action( 'bffrm_settings_fields', function ( \BlueFairy\Forms\Settings $settings ) { /* echo <tr>…</tr> */ } );
// …and saves with it (read and sanitise your own $_POST fields):
add_filter( 'bffrm_settings_input', fn( array $input ) => $input );

// Below the fields on a submission's screen (Forms Pro: uploaded files):
add_action( 'bffrm_submission_detail_after', function ( array $submission, array $payload ) { /* echo … */ }, 10, 2 );

// Erase an add-on's own copy of submissions before personal-data erasure anonymises them:
add_action( 'bffrm_before_erase_submissions', function ( string $email_hash ) { /* … */ } );

// The proxies whose X-Forwarded-For / X-Real-IP is believed (IP or CIDR), and Cloudflare's ranges:
add_filter( 'bffrm_trusted_proxies', fn( array $proxies ) => $proxies );
add_filter( 'bffrm_cloudflare_ranges', fn( array $ranges ) => $ranges );

// The fields the submission screen and the personal-data export show for a stored row
// (an add-on that stores the payload elsewhere, e.g. encrypted, supplies it here):
// The admin notification's headers (Reply-To the visitor is already there, 1.1.9):
add_filter( 'bffrm_notification_headers', fn( array $headers, array $form, array $submission ) => $headers, 10, 3 );

add_filter( 'bffrm_submission_display_payload', fn( array $payload, array $submission ) => $payload, 10, 2 );

Database Tables

  • {prefix}bffrm_forms — form definitions
  • {prefix}bffrm_submissions — submission records
  • {prefix}bffrm_rate_limits — atomic rate-limit counters
  • {prefix}bffrm_audit_log — admin action audit trail

License

GPL-2.0-or-later — see LICENSE.

Support the free plugin

This plugin is free and always will be. If it saves you time, you can buy us a coffee on Ko-fi ☕ — it helps keep the free plugins tested and maintained.

Found a bug or have an idea? Open an issue. Security problems: see SECURITY.md.