Vora Forms documentation
A drag-and-drop form builder that stays out of the way — fields, conditional logic, multi-step forms, entries, notifications and spam protection.
Install
- 1Upload the vora-forms folder to /wp-content/plugins/, or install the zip from Plugins → Add New → Upload Plugin.
- 2Activate the plugin.
- 3Go to Vora Forms → Add New and build your first form.
- 4Copy the shortcode and paste it into any page or post.
The five screens
All under one top-level Vora Forms menu.
- All Forms
Every form you have built, with its shortcode ready to copy.
- Add New
The drag-and-drop builder.
- Entries
Stored submissions, with search, filtering and CSV export. Suspected spam is filed here rather than deleted.
- Leads
What was forwarded to a mailing list or CRM, and what failed.
- Settings
Site-wide defaults: storage and retention, spam defaults for new forms, sender identity and email styling, lead-destination credentials, the accent colour, and the advanced options.
Building a form
Drop fields onto the canvas and drag them into the order you want. Each field can be full, half or third width, so two or three sit side by side on a row — a first and last name pair, or a city, county and postcode line.
A field exists when its driver does
The 14 field types
- Texttext
A single line.
- Emailemail
Validated as an address on the server, not only in the browser.
- Paragraphtextarea
Multi-line free text.
- Numbernumber
Numeric input.
- Phonetel
Telephone number.
- Websiteurl
A URL.
- Dropdownselect
One choice from a list.
- Multiple choiceradio
One choice, shown as radio buttons.
- Checkboxescheckbox
Any number of choices, including none.
- Datedate
A date picker.
- Hiddenhidden
Carries a fixed value through with the submission — a campaign name or a source, typically.
- Headingheading
A section title. Presentational: it collects nothing.
- HTMLhtml
Arbitrary markup between fields, for an explanation or a consent notice.
- Page breakpage-break
Splits the form into steps. See Multi-step forms below.
Conditional logic
Show or hide a field based on an earlier answer — reveal “Which product?” only after someone picks Support, or ask for a company name only from business enquiries. Because the form is rendered in the browser, the field appears and disappears as the visitor types, with no page reload.
Multi-step forms
Add a Page break field wherever you want the form to split. Everything before it becomes step one, everything after it step two, and so on. Progress can be shown as a bar or as numbered steps.
Steps are worth reaching for when a form is long enough that seeing all of it at once would put someone off — the count of fields on screen is what people judge, not the total.
Placing a form
Two ways, and they render the same form:
- Shortcode[vforms_form id="12"]
Copy it from All Forms and paste it into any page, post or widget area. The ID is the form's post ID.
- Block
A Vora Forms block in the editor, for anyone who would rather pick the form from a list than paste a shortcode.
- The old tag still works[lite_form]
Answered for pages written before the rename, so nothing that already exists stops rendering. New work should use [vforms_form].
Entries
- Storing submissionsstore_entries · default on
Every accepted submission is saved and appears under Entries, searchable and filterable, and exportable to CSV.
- Retentionentry_retention · default 0
Days to keep entries; 0 keeps them forever. Set a real number if the form collects anything you would rather not hold indefinitely — a retention period is the simplest data-protection control there is.
Turning storage off
Notifications
Two kinds, set per form: an admin notification to you, and an autoresponder to the person who submitted. Both support merge tags in the subject, the body and the recipient list.
- From name and addressfrom_name · from_email
Who notifications come from. Delivery goes through wp_mail(), so an SMTP plugin handles the actual sending.
- Email accentemail_accent · default #0f766e
Separate from the form's accent on purpose: an email is read on a white card in an inbox with none of the page around it, so what works on the site does not automatically work here. Header, row dividers and link colours are derived from this one value, and every shade is a solid hex rather than rgba() so Outlook renders it like everyone else.
- Footer noteemail_footer_note · default “Sent from {site_name} ({site_url})”
Yours to write, and it supports merge tags. Clear it and the footer row disappears entirely rather than leaving an empty strip.
These tags are available in every template:
- {form_title}
- {form_id}
- {entry_id}
- {site_name}
- {site_url}
- {admin_email}
- {user_ip}
- {date}
Field values are available as tags too, so an autoresponder can open with the name the visitor just gave you.
Lead destinations
A submission can be forwarded to a mailing list or CRM as well as stored: Mailchimp, HubSpot, Brevo, ActiveCampaign, MailerLite, Kit, or any endpoint of your own through the webhook destination. The Leads screen shows what was forwarded and what failed.
Why the keys are site-level, not per-form
Spam protection
Five layers, and the ones in Settings are the defaults applied to newly created forms — an existing form keeps what it was saved with.
- Honeypothoneypot · default on
A field a person never sees and a bot fills in. Submissions caught by it are dropped without a trace, and the visitor is shown the normal success message — so a bot learns nothing about why it failed.
- Timing checktime_trap · default 3 seconds
A submission that arrives faster than a human could have typed it is treated as spam. Raise it for long forms, lower it for a single-field signup.
- Rate limitingrate_limit · default 10
Submissions allowed per visitor before further attempts are refused.
- Captchacaptcha · default none
Per form, either a math question or distorted image characters. The challenge is fetched by the browser after the form loads rather than printed into the page, so a page cache cannot freeze it and hand every visitor the same question. The answer stays on the server, and each challenge is good for exactly one attempt — right or wrong — so a solved one cannot be replayed.
- Akismetakismet · default off
Uses your existing Akismet installation when one is present.
Suspected spam is filed, not deleted
Appearance
- One accent colouraccent_color · default #0f766e
Themes the whole form. Hover, focus-ring and tint shades are derived from it, and the label colour on buttons and checkboxes flips between white and dark automatically — whichever gives more contrast against the accent you picked. There is no combination of settings that produces unreadable text.
- Why teal-700 and not teal-600
The lighter shade cannot reach 4.5:1 against white or against dark text, so it has no accessible label colour at all. The default is the darker one for that reason.
- Front-end stylesheetload_frontend_css · default on
Turn it off if you would rather style the form entirely from your theme.
Advanced
- Trust proxy headerstrust_proxy_headers · default off
Turn this on when the site is behind Cloudflare or another proxy and every visitor appears to share one IP. Leave it off otherwise: on a site that is not behind a proxy, those headers can be forged by anyone, and believing them lets a bot walk straight past the rate limiter.
- Caching
The submit endpoint does not depend on a nonce, so a form served from a cached page still submits correctly.
Extending it
Field types come from a small registry, so an add-on can supply its own:
add_action( 'vforms_register_fields', function () {
require_once __DIR__ . '/class-field-rating.php';
Vora_Forms_Field_Registry::register( 'rating', 'My_Field_Rating' );
} );And there is an action after each accepted submission:
add_action( 'vforms_submission', function ( $entry_id, $form_id, $fields ) {
// Push to a CRM, and so on.
}, 10, 3 );A field appears in the builder exactly when a driver exists for it, so registering one is all that is needed — there is no second list to keep in step.
Troubleshooting
Does the form work with caching plugins?+–
Yes. The submit endpoint does not depend on a nonce, so a form served from a cached page still submits correctly. The captcha is fetched after load for the same reason.
Does it work without JavaScript?+–
No. The form is rendered by a small React bundle, which is what makes conditional logic and multi-step navigation work without a page reload. Visitors with JavaScript disabled see a short notice instead.
Can I use my own email provider?+–
Yes. Vora Forms sends through wp_mail(), so any SMTP or API mailer plugin you have installed handles delivery and logging with no extra configuration.
My site is behind Cloudflare and every visitor has the same IP+–
Turn on Settings → Advanced → Trust proxy headers. It is off by default because on a site that is not behind a proxy those headers can be forged by anyone, which would let a bot walk straight past the rate limiter.
The image captcha option is missing+–
It is hidden entirely on servers without the GD extension, rather than offered and silently downgraded. Use the math question, which is the better choice anyway — a screen reader can read it aloud, and an image captcha cannot be made accessible.
A real enquiry was marked as spam+–
It is in Entries, filed rather than deleted — every spam filter has false positives, and an enquiry that silently vanishes is worse than one sitting in a folder. Honeypot catches are the single exception: those are dropped without a trace.