This plugin allows you to build and manage custom forms directly within the admin panel. Instead of hard-coding a new form into your website or application every time you need one, admins can simply define the schema for each form they need on-the-fly, and your front-end can map over this schema, render its own UI components, and match your brand's design system.
All form submissions are stored directly in your database and are managed directly from the admin panel. When forms are submitted, you can display a custom on-screen confirmation message to the user or redirect them to a dedicated confirmation page. You can even send dynamic, personalized emails derived from the form's data. For example, you may want to send a confirmation email to the user who submitted the form, and also send a notification email to your team.
Forms can be as simple or complex as you need, from a basic contact form, to a multi-step lead generation engine, or even a donation form that processes payment. You may not need to reach for third-party services like HubSpot or Mailchimp for this, but instead use your own first-party tooling, built directly into your own application.
Install the plugin using any JavaScript package manager like Yarn, NPM, or PNPM:
In the plugins
array of your Payload config, call the plugin with options:
fields
(option)The fields
property is an object of field types to allow your admin editors to build forms with. To override default settings, pass either a boolean value or a partial Payload Block keyed to the block's slug. See Fields for more details.
redirectRelationships
The redirectRelationships
property is an array of collection slugs that, when enabled, are populated as options in the form's redirect
field. This field is used to redirect the user to a dedicated confirmation page upon form submission (optional).
beforeEmail
The beforeEmail
property is a beforeChange hook that is called just after emails are prepared, but before they are sent. This is a great place to inject your own HTML template to add custom styles.
formOverrides
Override anything on the forms
collection by sending a Payload Collection Config to the formOverrides
property.
formSubmissionOverrides
Override anything on the form-submissions
collection by sending a Payload Collection Config to the formSubmissionOverrides
property.
handlePayment
The handlePayment
property is a beforeChange hook that is called upon form submission. You can integrate into any third-party payment processing API here to accept payment based on form input. You can use the getPaymentTotal
function to calculate the total cost after all conditions have been applied. This is only applicable if the form has enabled the payment
field.
First import the utility function. This will execute all of the price conditions that you have set in your form's payment
field and returns the total price.
Then in your plugin's config:
Each field represents a form input. To override default settings pass either a boolean value or a partial Payload Block keyed to the block's slug. See Field Overrides for more details on how to do this.
Maps to a text
input in your front-end. Used to collect a simple string.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | string | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
Maps to a textarea
input on your front-end. Used to collect a multi-line string.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | string | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
Maps to a select
input on your front-end. Used to display a list of options.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | string | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
options | array | An array of objects with label and value properties. |
Maps to a text
input with type email
on your front-end. Used to collect an email address.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | string | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
Maps to a select
input on your front-end. Used to collect a US state.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | string | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
Maps to a select
input on your front-end. Used to collect a country.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | string | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
Maps to a checkbox
input on your front-end. Used to collect a boolean value.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | checkbox | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
Maps to a number
input on your front-end. Used to collect a number.
Property | Type | Description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | string | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
Maps to a RichText
component on your front-end. Used to display an arbitrary message to the user anywhere in the form.
property | type | description |
---|---|---|
message | richText | The message to display on the form. |
Add this field to your form if it should collect payment. Upon submission, the handlePayment
callback is executed with the form and submission data. You can use this to integrate with any third-party payment processing API.
property | type | description |
---|---|---|
name | string | The name of the field. |
label | string | The label of the field. |
defaultValue | number | The default value of the field. |
width | string | The width of the field on the front-end. |
required | checkbox | Whether or not the field is required when submitted. |
priceConditions | array | An array of objects that define the price conditions. See below for more details. |
Each of the priceConditions
are executed by the getPaymentTotal
utility that this plugin provides. You can call this function in your handlePayment
callback to dynamically calculate the total price of a form upon submission based on the user's input. For example, you could create a price condition that says "if the user selects 'yes' for this checkbox, add $10 to the total price".
property | type | description |
---|---|---|
fieldToUse | relationship | The field to use to determine the price. |
condition | string | The condition to use to determine the price. |
valueForOperator | string | The value to use for the operator. |
operator | string | The operator to use to determine the price. |
valueType | string | The type of value to use to determine the price. |
value | string | The value to use to determine the price. |
You can provide your own custom fields by passing a new Payload Block object into fields
. You can override or extend any existing fields by first importing the fields
from the plugin:
Then merging it into your own custom field:
This plugin relies on the email configuration defined in your payload.init()
. It will read from your config and attempt to send your emails using the credentials provided.
All types can be directly imported:
The Examples Directory contains an official Form Builder Plugin Example which demonstrates exactly how to configure this plugin in Payload and implement it on your front-end. We've also included an in-depth walk-through of how to build a form from scratch in our Form Builder Plugin Blog Post.
Below are some common troubleshooting tips. To help other developers, please contribute to this section as you troubleshoot your own application.
from
addresses in your form submission emails cannot be anything other than something@your_domain.com
. This means that from {{email}}
will not work, but website@your_domain.com
will. You can still send the form's email address in the body of the email.