{"id":322984,"date":"2026-06-17T06:45:23","date_gmt":"2026-06-17T06:45:23","guid":{"rendered":"https:\/\/de.wordpress.org\/plugins\/perform-forms\/"},"modified":"2026-07-14T10:23:36","modified_gmt":"2026-07-14T10:23:36","slug":"flinkform","status":"publish","type":"plugin","link":"https:\/\/fy.wordpress.org\/plugins\/flinkform\/","author":23152225,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.4.4","stable_tag":"1.4.4","tested":"7.0.1","requires":"6.5","requires_php":"8.1","requires_plugins":null,"header_name":"Flinkform - Forms for the Block Editor","header_author":"Dennis Buchwald","header_description":"Block-native form builder for the WordPress Block Editor \u2014 theme.json styling, conditional logic, Interactivity API.","assets_banners_color":"b6aacb","last_updated":"2026-07-14 10:23:36","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/flinkform.de\/","header_author_uri":"https:\/\/www.dennisbuchwald.de","rating":5,"author_block_rating":0,"active_installs":0,"downloads":424,"num_ratings":1,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.4.0":{"tag":"0.4.0","author":"dbwmediadennis","date":"2026-06-17 06:44:51"},"0.4.1":{"tag":"0.4.1","author":"dbwmediadennis","date":"2026-06-17 07:42:10"},"0.4.2":{"tag":"0.4.2","author":"dbwmediadennis","date":"2026-06-17 07:53:19"},"1.0.0":{"tag":"1.0.0","author":"dbwmediadennis","date":"2026-06-22 13:11:35"},"1.0.1":{"tag":"1.0.1","author":"dbwmediadennis","date":"2026-06-23 13:24:34"},"1.0.2":{"tag":"1.0.2","author":"dbwmediadennis","date":"2026-06-23 13:44:53"},"1.0.3":{"tag":"1.0.3","author":"dbwmediadennis","date":"2026-06-23 13:53:17"},"1.0.4":{"tag":"1.0.4","author":"dbwmediadennis","date":"2026-06-25 06:26:12"},"1.1.0":{"tag":"1.1.0","author":"dbwmediadennis","date":"2026-06-30 04:59:07"},"1.1.1":{"tag":"1.1.1","author":"dbwmediadennis","date":"2026-06-30 05:09:10"},"1.2.0":{"tag":"1.2.0","author":"dbwmediadennis","date":"2026-06-30 05:33:49"},"1.2.1":{"tag":"1.2.1","author":"dbwmediadennis","date":"2026-06-30 12:02:52"},"1.3.0":{"tag":"1.3.0","author":"dbwmediadennis","date":"2026-07-03 06:03:10"},"1.3.1":{"tag":"1.3.1","author":"dbwmediadennis","date":"2026-07-06 09:00:42"},"1.4.0":{"tag":"1.4.0","author":"dbwmediadennis","date":"2026-07-14 09:02:36"},"1.4.1":{"tag":"1.4.1","author":"dbwmediadennis","date":"2026-07-14 09:14:00"},"1.4.2":{"tag":"1.4.2","author":"dbwmediadennis","date":"2026-07-14 09:46:42"},"1.4.3":{"tag":"1.4.3","author":"dbwmediadennis","date":"2026-07-14 09:58:53"},"1.4.4":{"tag":"1.4.4","author":"dbwmediadennis","date":"2026-07-14 10:23:36"}},"upgrade_notice":{"0.4.2":"<p>German translation included. Success message, submit label and consent text now render in the site language automatically. Fixes a visual bug with the editor button in Spectra containers.<\/p>","0.4.0":"<p>The plugin was renamed to Flinkform. All settings prefixes changed; this version is intended for fresh installations.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":1},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3575326,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3575326,"resolution":"256x256","location":"assets","locale":"","width":256,"height":265}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3575326,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3575326,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"flinkform\/form":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/form","version":"0.1.0","title":"Flinkform Form","category":"flinkform","icon":"feedback","description":"A form container. Add field blocks inside to build your form.","keywords":["form","contact","formular","flinkform"],"textdomain":"flinkform","supports":{"html":false,"align":["wide","full"],"anchor":true,"interactivity":true},"attributes":{"formId":{"type":"string","default":""},"title":{"type":"string","default":""},"submitLabel":{"type":"string","default":"Send"},"successMessage":{"type":"string","default":"Thank you! Your message has been sent successfully."},"notifications":{"type":"object","default":{}},"appearance":{"type":"object","default":{}},"submitCondition":{"type":"object","default":{}},"spamProtection":{"type":"string","default":"auto","enum":["auto","builtin","none"]},"retentionDays":{"type":"number","default":0},"afterSubmit":{"type":"object","default":{"behaviour":"message","redirectUrl":"","appendSubmissionId":false,"appendFormId":false}}},"providesContext":{"flinkform\/formId":"formId","flinkform\/appearance":"appearance"},"editorScript":"file:.\/index.js","editorStyle":"file:.\/index.css","viewScriptModule":"file:.\/view.js","style":"file:.\/style-index.css","render":"file:.\/render.php"},"flinkform\/field-text":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-text","version":"0.1.0","title":"Text Field","category":"flinkform","icon":"editor-textcolor","description":"A single-line text input.","keywords":["text","input","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Text"},"placeholder":{"type":"string","default":""},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-email":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-email","version":"0.1.0","title":"Email Field","category":"flinkform","icon":"email","description":"An email input with format validation.","keywords":["email","input","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Email"},"placeholder":{"type":"string","default":""},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/page-break":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/page-break","version":"0.1.0","title":"Page Break","category":"flinkform","icon":"minus","description":"Splits the form into steps. Place between field blocks to start a new step in a multi-step form.","keywords":["page break","step","multi-step","wizard","funnel"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":""},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-url":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-url","version":"0.1.0","title":"URL Field","category":"flinkform","icon":"admin-links","description":"A website URL input with format validation.","keywords":["url","website","link","input","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Website"},"placeholder":{"type":"string","default":""},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-checkbox":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-checkbox","version":"0.1.0","title":"Checkbox Group","category":"flinkform","icon":"forms","description":"Multiple choices from a list of options.","keywords":["checkbox","multi","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Choose any"},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"options":{"type":"array","default":[{"label":"Option 1","value":"option-1"},{"label":"Option 2","value":"option-2"}]},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}},"requiredMessage":{"type":"string","default":""}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-consent":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-consent","version":"0.2.7","title":"Consent","category":"flinkform","icon":"privacy","description":"A required consent checkbox (e.g. a GDPR data-processing agreement) with an optional link to your privacy policy.","keywords":["consent","gdpr","privacy","agree","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"consentText":{"type":"string","default":"I agree to the processing of my personal data for the purpose of contact in accordance with the {privacy_policy}."},"required":{"type":"boolean","default":true},"fieldName":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":true},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/section-heading":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/section-heading","version":"0.1.0","title":"Section Heading","category":"flinkform","icon":"heading","description":"A visual divider with an optional title and description. Not a field \u2014 nothing is submitted.","keywords":["heading","divider","section"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"title":{"type":"string","default":"Section"},"description":{"type":"string","default":""},"headingLevel":{"type":"number","default":2},"fullWidth":{"type":"boolean","default":true},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-phone":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-phone","version":"0.1.0","title":"Phone Field","category":"flinkform","icon":"phone","description":"A phone number input.","keywords":["phone","tel","telefon","input","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Phone"},"placeholder":{"type":"string","default":""},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-date":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-date","version":"0.1.0","title":"Date Field","category":"flinkform","icon":"calendar-alt","description":"A date picker input.","keywords":["date","datum","calendar","input","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Date"},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}},"minDate":{"type":"string","default":""},"maxDate":{"type":"string","default":""}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-toggle":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-toggle","version":"0.1.0","title":"Toggle \/ Checkbox","category":"flinkform","icon":"yes","description":"A single checkbox \u2014 great for terms-of-service style consents.","keywords":["toggle","checkbox","consent","agree"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"I agree"},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-hidden":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-hidden","version":"0.1.0","title":"Hidden Field","category":"flinkform","icon":"hidden","description":"An invisible field that records context with the submission (page URL, user, date, or a static value).","keywords":["hidden","meta","context"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Hidden Field"},"fieldName":{"type":"string","default":""},"valueSource":{"type":"string","default":"static"},"staticValue":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-textarea":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-textarea","version":"0.1.0","title":"Textarea Field","category":"flinkform","icon":"editor-alignleft","description":"A multi-line text input.","keywords":["textarea","message","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Message"},"placeholder":{"type":"string","default":""},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"rows":{"type":"number","default":4},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-radio":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-radio","version":"0.1.0","title":"Radio Group","category":"flinkform","icon":"marker","description":"A single choice from a list of options.","keywords":["radio","choice","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Choose one"},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"options":{"type":"array","default":[{"label":"Option 1","value":"option-1"},{"label":"Option 2","value":"option-2"}]},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-select":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-select","version":"0.1.0","title":"Dropdown","category":"flinkform","icon":"menu-alt","description":"A dropdown \u2014 single or multi-select.","keywords":["select","dropdown","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Choose one"},"placeholder":{"type":"string","default":""},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"multiple":{"type":"boolean","default":false},"options":{"type":"array","default":[{"label":"Option 1","value":"option-1"},{"label":"Option 2","value":"option-2"}]},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"},"flinkform\/field-number":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"flinkform\/field-number","version":"0.1.0","title":"Number Field","category":"flinkform","icon":"calculator","description":"A numeric input with optional min, max and step.","keywords":["number","numeric","field"],"textdomain":"flinkform","parent":["flinkform\/form"],"supports":{"html":false,"reusable":false},"attributes":{"label":{"type":"string","default":"Number"},"placeholder":{"type":"string","default":""},"required":{"type":"boolean","default":false},"helpText":{"type":"string","default":""},"fieldName":{"type":"string","default":""},"min":{"type":"string","default":""},"max":{"type":"string","default":""},"step":{"type":"string","default":""},"fullWidth":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","default":{}}},"usesContext":["flinkform\/formId","flinkform\/appearance"],"editorScript":"file:.\/index.js","render":"file:.\/render.php"}},"tagged_versions":["0.4.0","0.4.1","0.4.2","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","1.2.0","1.2.1","1.3.0","1.3.1","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Block Editor \u2014 building a contact form with the Flinkform blocks","2":"Frontend \u2014 a styled single-step form on GeneratePress","3":"Multi-step form with progress bar","4":"Submissions list in wp-admin","5":"Submission detail view","6":"Conditional logic in the block inspector","7":"Style panel \u2014 field style, label position, colours"}},"plugin_section":[],"plugin_tags":[148857,130308,358,2253,601],"plugin_category":[42],"plugin_contributors":[248029],"plugin_business_model":[],"class_list":["post-322984","plugin","type-plugin","status-publish","hentry","plugin_tags-block-editor","plugin_tags-conditional-logic","plugin_tags-contact-form","plugin_tags-form-builder","plugin_tags-forms","plugin_category-contact-forms","plugin_contributors-dbwmediadennis","plugin_committers-dbwmediadennis"],"banners":{"banner":"https:\/\/ps.w.org\/flinkform\/assets\/banner-772x250.png?rev=3575326","banner_2x":"https:\/\/ps.w.org\/flinkform\/assets\/banner-1544x500.png?rev=3575326","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/flinkform\/assets\/icon-128x128.png?rev=3575326","icon_2x":"https:\/\/ps.w.org\/flinkform\/assets\/icon-256x256.png?rev=3575326","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Flinkform is a form builder that lives entirely inside the WordPress Block Editor. Forms are composed from native blocks (<code>block.json<\/code> v3), styled through <code>theme.json<\/code> design tokens, and powered by the Interactivity API \u2014 no separate admin UI, no shortcodes, no jQuery.<\/p>\n\n<h4>How it works<\/h4>\n\n<ul>\n<li><strong>Block Editor native<\/strong> \u2014 forms are built with <code>block.json<\/code> and the Interactivity API, directly inside the editor<\/li>\n<li><strong>theme.json styling<\/strong> \u2014 forms inherit your theme's typography, colours and spacing automatically<\/li>\n<li><strong>Modern stack<\/strong> \u2014 WordPress 6.5+, PHP 8.1+, no jQuery, frontend JS under 15 KB gzipped<\/li>\n<li><strong>Multi-step forms<\/strong> \u2014 split long forms into steps with a Page Break block, included in the free core<\/li>\n<li><strong>Conditional logic<\/strong> \u2014 show\/hide fields based on user input, included in the free core<\/li>\n<li><strong>WCAG 2.1 AA<\/strong> \u2014 full keyboard navigation, screen-reader compatible, aria-live announcements<\/li>\n<li><strong>Privacy by design<\/strong> \u2014 no external services, no tracking cookies, no IP tracking \u2014 everything stays on your server<\/li>\n<\/ul>\n\n<h4>Features (free core)<\/h4>\n\n<p><strong>Form building<\/strong>\n* 13 field types: Text, Email, Textarea, Number, Date, URL, Phone, Select, Radio, Checkbox, Toggle, Hidden, Section Heading\n* Dedicated Consent field for privacy-policy agreement\n* Multi-step forms with Page Break block, per-step validation and progress indicator (bar, dots or numbers)\n* Conditional logic \u2014 show\/hide fields, skip steps, gate the submit button\n* Two-column layout with per-field full-width override<\/p>\n\n<p><strong>Styling<\/strong>\n* Automatic theme.json inheritance (colours, typography, spacing, border radius)\n* Style panel: primary colour, field style (bordered\/soft\/underline\/minimal), label position (above\/beside\/floating\/placeholder), submit button style (fill\/outline\/ghost)<\/p>\n\n<p><strong>Notifications<\/strong>\n* Admin notification email on every submission (configurable recipient, merge tags)\n* Optional confirmation email to the submitter\n* Sends through your site's standard WordPress mail (<code>wp_mail<\/code>)<\/p>\n\n<p><strong>Spam protection<\/strong>\n* Always-on honeypot + signed time-based check (zero configuration)\n* Built-in proof-of-work challenge with accessible math fallback for visitors without JavaScript\n* No external service, no API keys, no tracking cookies, 100% GDPR-friendly<\/p>\n\n<p><strong>After submission<\/strong>\n* Success message or redirect to a custom thank-you URL (with open-redirect protection)\n* Optional submission ID and form ID query parameters for conversion tracking (GA4, Meta Pixel, Plausible, etc.)<\/p>\n\n<p><strong>Admin<\/strong>\n* Submissions list with search, filter by form, sort, bulk actions\n* Single-submission detail view with all field labels and values\n* Mark as read\/unread\n* Per-form data retention with automatic daily purge<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>Flinkform is built with privacy by default. Here is what the free core does and does not do:<\/p>\n\n<p><strong>What the free core stores:<\/strong>\n* Form submissions (the field values visitors enter) in a dedicated database table (<code>{prefix}flinkform_submissions<\/code>)<\/p>\n\n<p><strong>What the free core does NOT do:<\/strong>\n* It stores no IP addresses and no browser user-agent strings\n* It sets no tracking, analytics or marketing cookies. Flinkform sets exactly one strictly-necessary cookie \u2014 <code>flinkform_flash<\/code> (lifetime ~60 seconds, httpOnly) \u2014 and only when a form submission fails validation, to carry the error message and the visitor's input across the page reload. Successful submissions set no cookie at all\n* It contacts no external service<\/p>\n\n<p><strong>Data retention:<\/strong>\n* By default, submissions are retained until you delete them. To comply with the storage-limitation principle (GDPR Art. 5), set a per-form retention period (Form block \u2192 Data Retention) and Flinkform deletes older submissions automatically each day\n* Individual submissions can be deleted from the admin submissions screen at any time<\/p>\n\n<p><strong>Data deletion:<\/strong>\n* All free-core data (the submissions table) is permanently removed when the plugin is uninstalled through the WordPress admin\n* Flinkform integrates with WordPress's privacy tools (Tools &gt; Export Personal Data \/ Erase Personal Data) to support data-subject access and erasure requests<\/p>\n\n<h3>Source Code<\/h3>\n\n<p>The complete, uncompiled source code (including the <code>src\/<\/code> directory with the\nunminified JavaScript\/CSS that compiles into <code>build\/<\/code>) is publicly available at:\nhttps:\/\/github.com\/dennisbuchwald\/Flinkform<\/p>\n\n<p>Build instructions (Node.js 18+ and npm required):\n1. Clone the repository: <code>git clone https:\/\/github.com\/dennisbuchwald\/Flinkform.git<\/code>\n2. Install dependencies: <code>npm install<\/code>\n3. Build the compiled assets into <code>build\/<\/code>: <code>npm run build<\/code><\/p>\n\n<p>The build is powered by <code>@wordpress\/scripts<\/code> (webpack). The <code>src\/<\/code> sources are\nexcluded from the distributed plugin zip to keep it small; this repository is\nthe canonical, reviewable source.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>flinkform<\/code> folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> screen in WordPress<\/li>\n<li>Open any page or post in the Block Editor<\/li>\n<li>Insert the <strong>Form<\/strong> block (search for \"Flinkform\" or \"Form\")<\/li>\n<li>Add fields, configure settings in the block inspector, publish \u2014 done<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20flinkform%20free%3F\"><h3>Is Flinkform free?<\/h3><\/dt>\n<dd><p>Yes. Flinkform is GPLv2-licensed and completely free \u2014 including multi-step forms and conditional logic. Everything you need to build and run real forms is in the core.<\/p><\/dd>\n<dt id=\"what%20wordpress%20version%20do%20i%20need%3F\"><h3>What WordPress version do I need?<\/h3><\/dt>\n<dd><p>WordPress 6.5 or higher and PHP 8.1 or higher. Flinkform uses modern WordPress APIs (Interactivity API, block.json v3, viewScriptModule) that are not available in older versions.<\/p><\/dd>\n<dt id=\"does%20flinkform%20work%20with%20my%20theme%3F\"><h3>Does Flinkform work with my theme?<\/h3><\/dt>\n<dd><p>Yes. Flinkform reads your theme's design tokens from <code>theme.json<\/code> and inherits colours, typography, spacing and border radius automatically. Forms look native on any modern WordPress theme \u2014 tested with GeneratePress, Twenty Twenty-Five, Astra and Kadence.<\/p><\/dd>\n<dt id=\"does%20flinkform%20support%20multi-step%20forms%3F\"><h3>Does Flinkform support multi-step forms?<\/h3><\/dt>\n<dd><p>Yes, in the free core. Insert a <strong>Page Break<\/strong> block between fields to split the form into steps, choose a progress indicator style (bar, dots or numbers), and benefit from per-step validation. Steps can even be skipped conditionally based on earlier answers.<\/p><\/dd>\n<dt id=\"how%20does%20the%20spam%20protection%20work%3F\"><h3>How does the spam protection work?<\/h3><\/dt>\n<dd><p>Flinkform uses a layered approach that requires no setup:<\/p>\n\n<ol>\n<li><strong>Honeypot<\/strong> \u2014 a hidden field that bots fill in but humans never see<\/li>\n<li><strong>Signed time check<\/strong> \u2014 submissions faster than a couple of seconds after page load are rejected; the timestamp is cryptographically signed so bots cannot forge it<\/li>\n<li><strong>Proof-of-work challenge<\/strong> \u2014 the visitor's browser solves a small computational puzzle in the background; visitors without JavaScript get a simple math question instead<\/li>\n<\/ol>\n\n<p>No external service is contacted. No tracking cookies are set. No personal data is shared.<\/p><\/dd>\n<dt id=\"is%20flinkform%20gdpr-compliant%3F\"><h3>Is Flinkform GDPR-compliant?<\/h3><\/dt>\n<dd><p>Flinkform is designed with privacy by default \u2014 see the Privacy section below for the full detail. In short: no IP addresses or user-agent strings are stored, no data ever leaves your server, no external spam service is used, and Flinkform integrates with WordPress's privacy tools for data-subject access and erasure requests.<\/p><\/dd>\n<dt id=\"my%20notification%20emails%20don%27t%20arrive.%20what%20can%20i%20do%3F\"><h3>My notification emails don't arrive. What can I do?<\/h3><\/dt>\n<dd><p>Email deliverability depends on your host. Many hosts send <code>wp_mail()<\/code> unreliably. If your notifications don't arrive, install a dedicated SMTP plugin to route mail through a proper provider \u2014 it will handle delivery for Flinkform too.<\/p><\/dd>\n<dt id=\"can%20i%20redirect%20to%20a%20thank-you%20page%20after%20submission%3F\"><h3>Can I redirect to a thank-you page after submission?<\/h3><\/dt>\n<dd><p>Yes. In the block inspector's \"After Submit\" panel, choose \"Redirect to URL\" and enter your thank-you page URL (validated against open redirects). Optionally append the submission ID and form ID as query parameters for conversion tracking.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.4.4<\/h4>\n\n<ul>\n<li>Fix: forms embedded outside the current page's own content \u2014 in a footer or header template part, a synced pattern, a theme-builder element or a site-wide popup \u2014 were silently rejected on submit, because the submission was matched only against the current page's content. Submissions now resolve the form wherever it actually lives, so popup and footer forms save correctly.<\/li>\n<\/ul>\n\n<h4>1.4.3<\/h4>\n\n<ul>\n<li>Critical fix: a variable-ordering error introduced in 1.4.0 aborted the whole frontend module on load \u2014 the proof-of-work spam solver never ran, so EVERY submission (popup or not) was silently rejected as spam and nothing was stored. If you are on 1.4.0-1.4.2, update immediately.<\/li>\n<\/ul>\n\n<h4>1.4.2<\/h4>\n\n<ul>\n<li>Fix: popup submissions now actually use the fetch path \u2014 the hidden admin-post \"action\" input shadowed the form's action property in JavaScript, so every fetch went to a broken URL and silently fell back to the classic page-reload submit<\/li>\n<li>Change: the spam-challenge token lifetime is now 30 minutes (was 5) \u2014 visitors who read a long page or open a popup form some minutes after page load were silently rejected with no feedback and no stored submission<\/li>\n<\/ul>\n\n<h4>1.4.1<\/h4>\n\n<ul>\n<li>Fix: the spam-challenge token is now consumed when a submission is accepted instead of when it is checked \u2014 a popup submission that failed validation can be corrected and resubmitted without hitting the replay guard (the popup flow never re-renders the page, so no fresh token is minted between attempts)<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>New: forms inside popups\/modals now submit via fetch() without a page reload \u2014 the success card and validation errors render inline, so the popup stays open and the visitor sees the outcome<\/li>\n<li>Applies automatically when a form sits inside a modal container (<code>[role=\"dialog\"]<\/code>, a native <code>&lt;dialog&gt;<\/code> element, or the dbw popup block); forms in the normal page flow keep the exact same behaviour as before<\/li>\n<li>All server-side protections (nonce, honeypot, time-check, spam challenge, duplicate-submission guard) run unchanged; redirect-after-submit still works from popups and network errors fall back to the classic submission<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Update: plugin homepage now points to the dedicated product site at flinkform.de<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: duplicate-submission protection \u2014 a double-click, back-button resubmit or parallel request no longer creates a second entry, duplicate notification emails or repeated side effects (webhooks, payment verification in Pro)<\/li>\n<li>New: <code>flinkform_admin_format_value<\/code> filter \u2014 add-ons can format field values on the submission detail view (Flinkform Pro uses it to render uploaded files as download links)<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Fix: pages with a Flinkform are now excluded from full-page caching (DONOTCACHEPAGE) \u2014 prevents stale spam-challenge tokens from silently rejecting submissions on cached pages<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>UX: redesigned error messages with inline icon, subtle background on global errors, and a gentle shake animation on invalid fields<\/li>\n<li>UX: consent field shows a clear \"Please agree to continue\" error instead of the internal field name<\/li>\n<li>UX: removed the thick left-border error indicator in favour of a cleaner full-border highlight<\/li>\n<\/ul>\n\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>UX: consent field error message fix (included in 1.2.0)<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Fix: consent checkbox is now correctly enforced as required during server-side validation (previously the required attribute was lost because Gutenberg does not serialise defaults)<\/li>\n<li>GDPR: new default consent text with inline privacy-policy link (replaces the old appended link)<\/li>\n<li>GDPR: consent text supports a <code>{privacy_policy}<\/code> placeholder that renders as an inline link to the site's privacy-policy page<\/li>\n<li>UX: updated default success message to \"Thank you! Your message has been sent successfully.\"<\/li>\n<li>Backwards-compatible: forms saved with the old consent text or success message automatically use the new defaults<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>i18n: regenerate German (de_DE) translation files (.mo + .json) to ensure all editor strings are up to date<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Style: reduce consent checkbox label to 12px for a cleaner visual hierarchy<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Floating labels now work on all text-input field types (URL, phone, date, select) - previously only text, email, textarea and number were supported<\/li>\n<li>Date and select fields start with the label in the lifted\/notched position since they always show native browser UI<\/li>\n<li>Beside and hidden label positions now also apply to URL, phone, date and select fields<\/li>\n<li>Fix: style toggle buttons (field style, label position) no longer overflow in the editor sidebar, especially with longer translated labels<\/li>\n<li>First stable release<\/li>\n<\/ul>\n\n<h4>0.4.2<\/h4>\n\n<ul>\n<li>i18n: block attribute defaults (success message, submit label, consent text) are now translated at render time - existing forms on non-English sites display the correct language without manual editing<\/li>\n<li>i18n: complete German (de_DE) translation - all frontend text, editor UI, admin screens and validation messages<\/li>\n<li>i18n: load bundled translations via load_plugin_textdomain() so they work without waiting for translate.wordpress.org<\/li>\n<li>Fix: the \"Add field\" editor button no longer inherits a 62 px font-size when the form block is placed inside a Spectra\/UAGB container<\/li>\n<\/ul>\n\n<h4>0.4.0<\/h4>\n\n<ul>\n<li>Renamed the plugin to Flinkform (new slug, text domain, prefixes <code>flinkform_<\/code>\/<code>FLINKFORM_<\/code>, block namespace <code>flinkform\/*<\/code>)<\/li>\n<li>Security: the spam time-check timestamp is now HMAC-signed and form-bound, so it can no longer be forged<\/li>\n<li>Security: additional sanitisation on the notification Reply-To header<\/li>\n<li>Reliability: the daily retention purge is now guarded against overlapping cron runs<\/li>\n<li>Corrected the FAQ: multi-step forms are part of the free core (and always were since 0.2.7)<\/li>\n<li>Fixed the plugin and author URIs to use a resolvable host (www.dennisbuchwald.de)<\/li>\n<li>Documented the public source repository and build steps in the readme (Source Code section)<\/li>\n<li>Output escaping: conditional-logic data attributes are now escaped late at render time (esc_attr), and submission detail values are output via wp_kses_post()<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Renamed all WordPress-global prefixes to satisfy WordPress.org naming requirements<\/li>\n<li>Revised readme description to remove promotional language<\/li>\n<\/ul>\n\n<h4>0.2.9<\/h4>\n\n<ul>\n<li>WordPress.org Plugin Check pass: documented the safe direct custom-table queries, fixed admin sort-order input handling, sanitised spam\/honeypot inputs \u2014 no functional change<\/li>\n<li>Resolved all Plugin Check errors and warnings (output escaping is handled internally; queries are prepared)<\/li>\n<\/ul>\n\n<h4>0.2.8<\/h4>\n\n<ul>\n<li>Added a dedicated Consent field (GDPR), per-form retention auto-purge, and a GPLv2 LICENSE file<\/li>\n<li>Accessibility: explicit focus rings for checkboxes\/radios\/toggles, High-Contrast-Mode-safe focus on the soft field style, aria-invalid on group\/consent errors, improved contrast<\/li>\n<li>Hardening: mail subject + Reply-To stripped of CR\/LF; privacy-policy strings escaped; webhook header REST input sanitised<\/li>\n<li>Privacy text now documents the retention period and the strictly-necessary flash cookie<\/li>\n<\/ul>\n\n<h4>0.2.7<\/h4>\n\n<ul>\n<li>Architecture refactor: the core stays fully free (incl. multi-step + conditional logic); integration features (webhooks, SMTP, CSV export) were factored out of the core<\/li>\n<li>Privacy: full WordPress privacy-tools integration (exporter + eraser); accurate disclosure of the single strictly-necessary flash cookie<\/li>\n<li>Accessibility: broader <code>prefers-reduced-motion<\/code> coverage; required spam-math fallback for no-JS visitors<\/li>\n<li>Hardening: defence-in-depth against mail-header injection; open-redirect-safe thank-you redirects<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial build<\/li>\n<\/ul>","raw_excerpt":"Block-native form builder for the WordPress Block Editor \u2014 theme.json styling, multi-step forms, conditional logic, Interactivity API.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/322984","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=322984"}],"author":[{"embeddable":true,"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/dbwmediadennis"}],"wp:attachment":[{"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=322984"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=322984"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=322984"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=322984"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=322984"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/fy.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=322984"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}