{"id":381825,"date":"2026-10-27T22:38:32","date_gmt":"2026-10-27T22:38:32","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/pubforms\/"},"modified":"2026-10-27T22:37:56","modified_gmt":"2026-10-27T22:37:56","slug":"pubforms","status":"publish","type":"plugin","link":"https:\/\/ja.wordpress.org\/plugins\/pubforms\/","author":23580033,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.3.2","stable_tag":"0.3.2","tested":"7.1.4","requires":"6.3","requires_php":"7.4","requires_plugins":null,"header_name":"PubForms","header_author":"Pubtly","header_description":"Simple, privacy-friendly forms. Build a form, place it with a shortcode or block, and keep every submission in your own site.","assets_banners_color":"97aeca","last_updated":"2026-10-27 22:37:56","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/pubtly.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":54,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.3.2":{"tag":"0.3.2","author":"pubtly","date":"2026-10-27 22:37:56","revision":3769628}},"upgrade_notice":{"0.3.2":"<p>Security and privacy update: uploads and signatures are now private, signatures are validated, saving unfinished forms is off by default (switch it on per form), and only administrators can set webhooks.<\/p>","0.3.1":"<p>Security update: forms now include a nonce and uploads use the WordPress upload handler. If you use a caching layer that ignores no-cache headers, exclude pages that contain forms. Deleting the plugin now keeps your data unless the delete-on-uninstall setting is on.<\/p>","0.3.0":"<p>Adds a site-wide spam-protection setting, block styling options, and write-only secret keys. Review PubForms &gt; Settings after updating: forms that did not choose a CAPTCHA now follow the site-wide setting.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3769628,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3769628,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3769628,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3769628,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"pubforms\/form":{"name":"pubforms\/form","title":"PubForms Form"}},"tagged_versions":["0.3.2"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3769628,"resolution":"1","location":"assets","locale":"","width":1054,"height":1013},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3769628,"resolution":"2","location":"assets","locale":"","width":685,"height":949},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3769628,"resolution":"3","location":"assets","locale":"","width":652,"height":864},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3769628,"resolution":"4","location":"assets","locale":"","width":1084,"height":167}},"screenshots":{"1":"The form builder with the template picker and colour-coded field cards.","2":"A published form on a page, protected by Cloudflare Turnstile.","3":"A dropdown field on a published form.","4":"The Entries overview for your forms."}},"plugin_section":[],"plugin_tags":[358,2253,601,396],"plugin_category":[42,54],"plugin_contributors":[289074,289075],"plugin_business_model":[],"class_list":["post-381825","plugin","type-plugin","status-publish","hentry","plugin_tags-contact-form","plugin_tags-form-builder","plugin_tags-forms","plugin_tags-privacy","plugin_category-contact-forms","plugin_category-security-and-spam-protection","plugin_contributors-pubtly","plugin_contributors-steveomics","plugin_committers-pubtly"],"banners":{"banner":"https:\/\/ps.w.org\/pubforms\/assets\/banner-772x250.png?rev=3769628","banner_2x":"https:\/\/ps.w.org\/pubforms\/assets\/banner-1544x500.png?rev=3769628","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/pubforms\/assets\/icon-128x128.png?rev=3769628","icon_2x":"https:\/\/ps.w.org\/pubforms\/assets\/icon-256x256.png?rev=3769628","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/pubforms\/assets\/screenshot-1.png?rev=3769628","caption":"The form builder with the template picker and colour-coded field cards."},{"src":"https:\/\/ps.w.org\/pubforms\/assets\/screenshot-2.png?rev=3769628","caption":"A published form on a page, protected by Cloudflare Turnstile."},{"src":"https:\/\/ps.w.org\/pubforms\/assets\/screenshot-3.png?rev=3769628","caption":"A dropdown field on a published form."},{"src":"https:\/\/ps.w.org\/pubforms\/assets\/screenshot-4.png?rev=3769628","caption":"The Entries overview for your forms."}],"raw_content":"<!--section=description-->\n<p>PubForms lets you build a form in the WordPress admin, drop it into any page with a shortcode or the PubForms block, and read the submissions in your own dashboard.<\/p>\n\n<ul>\n<li><strong>20+ field types<\/strong>: text, email, paragraph, phone, URL, number, date, time, month, week, dropdown, multiple choice, checkboxes, quiz, file upload, signature, calculation, section heading, HTML, hidden and more<\/li>\n<li>Build contact forms and other common forms in seconds with ready-made templates<\/li>\n<li>Every submission is emailed to you and stored safely in your own database<\/li>\n<li>Read, search, sort and export entries to a spreadsheet (CSV) at any time<\/li>\n<li><strong>Conditional logic<\/strong> \u2014 show or hide a field based on how someone answers<\/li>\n<li><strong>Field calculations<\/strong> \u2014 total or multiply number fields automatically<\/li>\n<li><strong>Style it your way<\/strong>: pick a look, layout (stacked, grid or flow), spacing, corners, button position and colours in the block sidebar, or set them on the shortcode<\/li>\n<li><strong>Anti-spam<\/strong> you can switch on once for every form: Cloudflare Turnstile, hCaptcha or a built-in question, plus a hidden trap field, rate limiting, a minimum fill time, a link limit and a blocked-words list that work with no CAPTCHA at all<\/li>\n<li>Every input is validated and sanitised, so forms are safe from injection-style attacks<\/li>\n<li>Optional multi-page forms and save-&amp;-resume for longer submissions<\/li>\n<\/ul>\n\n<p>Everything runs on your own server: no IP addresses or browser details are stored with entries. Nothing is sent to a third-party service unless you turn on Cloudflare Turnstile, hCaptcha or a webhook (see External services below).<\/p>\n\n<h3>External services<\/h3>\n\n<p>PubForms works fully on its own. It contacts an outside service only if you switch one of these features on.<\/p>\n\n<h4>Cloudflare Turnstile (optional CAPTCHA)<\/h4>\n\n<p>Used when you choose Cloudflare Turnstile under PubForms &gt; Settings and save your Turnstile keys. A form then loads Cloudflare's script from <code>https:\/\/challenges.cloudflare.com\/turnstile\/v0\/api.js<\/code>, and the visitor's browser talks to Cloudflare to complete the check. When the form is submitted, your server sends the visitor's check token and your secret key to <code>https:\/\/challenges.cloudflare.com\/turnstile\/v0\/siteverify<\/code> to confirm it. The \"Test these keys\" button on the Settings screen does the same for one test token. Terms: https:\/\/www.cloudflare.com\/website-terms\/ - Privacy policy: https:\/\/www.cloudflare.com\/privacypolicy\/<\/p>\n\n<h4>hCaptcha (optional CAPTCHA)<\/h4>\n\n<p>Used when you choose hCaptcha under PubForms &gt; Settings and save your hCaptcha keys. A form then loads hCaptcha's script from <code>https:\/\/hcaptcha.com\/1\/api.js<\/code>, and the visitor's browser talks to hCaptcha to complete the check. When the form is submitted, your server sends the visitor's check token and your secret key to <code>https:\/\/hcaptcha.com\/siteverify<\/code> to confirm it. The \"Test these keys\" button does the same for one test token. Terms: https:\/\/www.hcaptcha.com\/terms - Privacy policy: https:\/\/www.hcaptcha.com\/privacy<\/p>\n\n<h4>Webhooks (optional)<\/h4>\n\n<p>If you add webhook URLs to a form, each confirmed submission is sent as JSON to those addresses, which an administrator chooses. Uploaded files are not sent, only their names. Requests to private or internal network addresses are refused. What the receiving service does with the data is governed by that service.<\/p>\n\n<p>The built-in question, trap field, rate limit, minimum fill time, link limit and blocked-words list all run on your own server and contact nothing.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code> and activate it.<\/li>\n<li>Go to PubForms &gt; Add New, build your form and publish it.<\/li>\n<li>Paste the shortcode shown on the form screen into a page, or add the PubForms Form block.<\/li>\n<li>Make sure your site can send email (an SMTP plugin is recommended) so notifications arrive.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"where%20are%20submissions%20stored%3F\"><h3>Where are submissions stored?<\/h3><\/dt>\n<dd><p>In a table in your WordPress database. They are not sent anywhere else.<\/p><\/dd>\n<dt id=\"why%20are%20notification%20emails%20not%20arriving%3F\"><h3>Why are notification emails not arriving?<\/h3><\/dt>\n<dd><p>WordPress sends mail through your server, which many hosts do not deliver reliably. Use an SMTP or transactional email plugin.<\/p><\/dd>\n<dt id=\"how%20is%20pubforms%20different%3F\"><h3>How is PubForms different?<\/h3><\/dt>\n<dd><p>It is built around privacy and simplicity: entries live in your own database, no visitor IP address or browser details are stored with them, there is no account or subscription, and spam protection works without any third-party CAPTCHA if you prefer. For rate limiting only, a one-way hash of the visitor's address is kept for an hour and never shown.<\/p><\/dd>\n<dt id=\"do%20i%20need%20a%20captcha%20account%3F\"><h3>Do I need a CAPTCHA account?<\/h3><\/dt>\n<dd><p>No. The built-in question, hidden trap field, rate limit, minimum fill time, link limit and blocked-words list need no account. Cloudflare Turnstile and hCaptcha are optional and need their own free keys.<\/p><\/dd>\n<dt id=\"can%20i%20change%20how%20an%20embedded%20form%20looks%3F\"><h3>Can I change how an embedded form looks?<\/h3><\/dt>\n<dd><p>Yes. Select the PubForms Form block and use the Layout, Form style and Colors panels in the sidebar. The shortcode takes the same options, for example <code>[pubforms id=\"123\" preset=\"soft\" layout=\"grid\" density=\"compact\" accent=\"#db2777\"]<\/code>.<\/p><\/dd>\n<dt id=\"does%20pubforms%20work%20with%20page%20caching%3F\"><h3>Does PubForms work with page caching?<\/h3><\/dt>\n<dd><p>Yes. Each form carries a security token (nonce) that expires, so pages that contain a form are sent with \"do not cache\" headers and flagged for the common caching plugins (WP Super Cache, W3 Total Cache, WP Rocket, LiteSpeed Cache and others). If your host or CDN caches pages regardless (for example a \"cache everything\" rule), exclude the pages that contain your forms, or visitors who load a stale copy will be asked to submit again.<\/p><\/dd>\n<dt id=\"are%20uploaded%20files%20and%20signatures%20private%3F\"><h3>Are uploaded files and signatures private?<\/h3><\/dt>\n<dd><p>Yes. They are saved in <code>wp-content\/uploads\/pubforms\/<\/code> with random file names, behind a deny-all <code>.htaccess<\/code> and an empty <code>index.php<\/code>, and the plugin never links to them by URL. You open them from an entry in the admin, which checks that you are signed in and can edit the form. On a server that ignores <code>.htaccess<\/code> (nginx, for example), block direct access to <code>\/wp-content\/uploads\/pubforms\/<\/code> in the server configuration, or move the folder outside the web root with the <code>pubforms_uploads_basedir<\/code> filter.<\/p><\/dd>\n<dt id=\"does%20pubforms%20save%20what%20visitors%20type%20before%20they%20submit%3F\"><h3>Does PubForms save what visitors type before they submit?<\/h3><\/dt>\n<dd><p>Only if you turn it on, per form, with \"Save what a visitor has typed if they leave without submitting\" in the form's settings. It is off by default. When it is on, the form shows a short notice, and answers typed so far (never files or signatures) are sent to your own site after a pause or when the visitor leaves, and are listed under \"Abandoned\" in Entries. Check that this fits your privacy policy and local law before you enable it.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20data%20if%20i%20delete%20the%20plugin%3F\"><h3>What happens to my data if I delete the plugin?<\/h3><\/dt>\n<dd><p>Nothing, unless you ask for it. Forms, submissions and settings are kept by default. To remove them when the plugin is deleted, tick \"Remove all forms and submissions when the plugin is deleted\" under PubForms &gt; Settings first.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.3.2<\/h4>\n\n<ul>\n<li>Privacy: saving what a visitor typed before they submit (\"Abandoned\" entries) is now a per-form setting that is off by default, shows a notice on the form, and never sends files or signatures. Existing forms need it switched on again<\/li>\n<li>Security: only administrators can set a form's webhook URLs, and webhooks use WordPress's safe HTTP API, which refuses internal network addresses<\/li>\n<li>Security: the per-visitor rate-limit key is a keyed hash (<code>wp_hash()<\/code>), the HTML field is filtered again when it is shown, and a note can only be saved on an entry of the form being edited<\/li>\n<li>Fix: the saved answers kept after a failed submission are stored under a lowercase key, so they are restored on sites with a persistent object cache; saved answers no longer keep multi-megabyte signature images, and saving a draft shares the per-visitor hourly limit<\/li>\n<li>Security: uploaded files and signatures are no longer publicly reachable. They are stored under a deny-all folder with random file names and are served only through the admin to signed-in users who can edit the form<\/li>\n<li>Security: drawn signatures are decoded and checked as a real PNG (chunk structure, CRC, dimensions), rewritten without any extra data, and rejected otherwise<\/li>\n<li>Notification emails and webhook payloads no longer contain a direct file link; open the entry in the admin to download a file. Webhooks carry the file name<\/li>\n<li>Deleting a form, or the plugin with the delete-on-uninstall setting on, also removes its stored files<\/li>\n<li>New filter <code>pubforms_uploads_basedir<\/code> to keep uploads outside the web root<\/li>\n<\/ul>\n\n<h4>0.3.1<\/h4>\n\n<ul>\n<li>Security: form submissions and abandoned-draft captures now require a valid nonce; an expired page returns the visitor to the form with their answers kept<\/li>\n<li>Pages that contain a form are sent with no-cache headers so a stale nonce is never served<\/li>\n<li>File uploads are saved with the WordPress upload handler (<code>wp_handle_upload()<\/code>) instead of <code>move_uploaded_file()<\/code><\/li>\n<li>Uninstall now honours the \"Remove all forms and submissions when the plugin is deleted\" setting; data is kept by default<\/li>\n<li>Fix: \"Show a thank-you message\" now actually appears after a form is submitted<\/li>\n<li>The Contact template now makes Subject required, like Message<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Template picker: choose a starting template from cards; the fields and settings below update as soon as you pick one<\/li>\n<li>Modern builder: colour-coded field cards by type, compact rows, tidy options grid<\/li>\n<li>Modern front-end form styling with an accent colour you can override (<code>--pubforms-accent<\/code>)<\/li>\n<li>Block and shortcode style options: preset, layout (stacked, grid, flow), spacing, label position, corners, shadow, width, button position, colours<\/li>\n<li>Site-wide spam protection: choose one method (Cloudflare Turnstile, hCaptcha or a built-in question) for every form; a form can override or opt out<\/li>\n<li>Built-in question challenge with your own question list, plus a minimum fill time, link limit and blocked-words list<\/li>\n<li>Turnstile and hCaptcha secret keys are now write-only on the Settings screen, with a \"Test these keys\" button<\/li>\n<li>Suggested privacy wording now appears in the WordPress privacy-policy guide<\/li>\n<li>Assets reload automatically when files change<\/li>\n<li>Notification emails show the visitor's address at the top of the message instead of using a Reply-To header, which many mail services reject for mistyped addresses (sites can still add Reply-To with the <code>pubforms_notification<\/code> filter)<\/li>\n<li>Settings shows how form emails are delivered and works with mail plugins such as PubMail<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>New field types: file upload, phone, date, time, week, month, URL, radio, checkboxes, hidden, section heading, HTML, signature, calculation, quiz (graded)<\/li>\n<li>Per-field polish: placeholder, default value, help text, column width<\/li>\n<li>Conditional logic and multi-page forms with a progress bar<\/li>\n<li>Optional Cloudflare Turnstile \/ hCaptcha spam protection<\/li>\n<li>Save &amp; Resume and abandonment capture<\/li>\n<li>Webhooks for confirmed entries<\/li>\n<li>Survey\/poll\/quiz results; CSV export filters; private entry notes; global settings; WordPress privacy tools<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>First version: form builder, shortcode and block, entries with CSV export, email notifications.<\/li>\n<\/ul>","raw_excerpt":"Simple, privacy-friendly forms for WordPress. Build a form with a shortcode or block and keep every submission in your own site.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/381825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=381825"}],"author":[{"embeddable":true,"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/pubtly"}],"wp:attachment":[{"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=381825"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=381825"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=381825"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=381825"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=381825"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ja.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=381825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}