Recommended for you: Functions
Use serverless functions to run on-demand, server-side code without having to manage a dedicated server.
Netlify comes with built-in form handling that’s enabled by default. Our build bots do it by parsing your HTML files directly at deploy time, so there’s no need for you to make an API call or include extra JavaScript on your site.
Code an HTML form into any page on your site, add data-netlify="true"
or a netlify
attribute to the <form>
tag, and you can start receiving submissions in your Netlify site admin panel.
Your form’s name
attribute determines what we call the form in the Netlify app interface. If you have more than one form on a site, each form should have a different name
attribute.
Here’s an example:
<form name="contact" method="POST" data-netlify="true">
<p>
<label>Your Name: <input type="text" name="name" /></label>
</p>
<p>
<label>Your Email: <input type="email" name="email" /></label>
</p>
<p>
<label>Your Role: <select name="role[]" multiple>
<option value="leader">Leader</option>
<option value="follower">Follower</option>
</select></label>
</p>
<p>
<label>Message: <textarea name="message"></textarea></label>
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
When Netlify bots parse the static HTML for a form you’ve added, they automatically strip the data-netlify="true"
or netlify
attribute from the <form>
tag and inject a hidden input named form-name
. In the resulting HTML that’s deployed, the data-netlify="true"
or netlify
attribute is gone, and the hidden form-name
input’s value
matches the name
attribute of <form>
like this:
<input type="hidden" name="form-name" value="contact">
You don’t have to, but you can submit static HTML forms using AJAX.
A static HTML form submitted this way must have data-netlify=true
or a netlify
attribute inside its <form>
tag.
Here’s an AJAX form submission example using the fetch
API for a static HTML form:
const handleSubmit = (event) => {
event.preventDefault();
const myForm = event.target;
const formData = new FormData(myForm);
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams(formData).toString(),
})
.then(() => console.log("Form successfully submitted"))
.catch((error) => alert(error));
};
document
.querySelector("form")
.addEventListener("submit", handleSubmit);
Requirements for the request:
FormData
constructor. That object is then encoded using the URLSearchParams
constructor and converted to a string. Note that Netlify forms do not support JSON form data at this time."Content-Type": "application/x-www-form-urlencoded"
. If the form accepts file uploads, including a Content-Type
header is not recommended.You don’t need to include extra JavaScript on your site to use Netlify Forms. But, if you want to, you can use JavaScript to render a form client-side. You can also submit JavaScript-rendered forms over AJAX.
Our buildbots find your forms by parsing the HTML of your site when the build completes. This means that if you’re using JavaScript to render a form client-side, our buildbots won’t find it in the pre-built files. You can work around this:
Create a hidden HTML form with the data-netlify="true"
attribute or a netlify
attribute and input fields with name
attributes to match the inputs of your JavaScript-rendered form. You need to apply the same work around if you want to use our reCAPTCHA 2 integration, and create a div
element in the hidden HTML with the data-netlify-recaptcha="true"
attribute.
Add a hidden input to the JavaScript-rendered form or JSX form:
<input type="hidden" name="form-name" value="name_of_my_form" />
You can also find related tutorials on our blog:
While the two articles are fairly framework-specific, the code demonstrates how to prerender forms when working with them in a web application.
To submit a JavaScript-rendered form built with a framework like Gatsby or Nuxt, you can send an AJAX POST request to any path on your site. Requirements for the request:
form-name
input to your JavaScript-rendered form, you need to send a form-name
attribute in the AJAX POST request body."Content-Type": "application/x-www-form-urlencoded"
. If the form accepts file uploads, including a Content-Type
header is not recommended.Here’s an AJAX form submission code sample using the fetch
API for a JavaScript-rendered form. It uses Gatsby’s navigate
function to redirect to a custom page on form submission success.
const handleSubmit = (event) => {
event.preventDefault();
const myForm = event.target;
const formData = new FormData(myForm);
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams(formData).toString(),
})
.then(() => navigate("/thank-you/"))
.catch((error) => alert(error));
};
For a JavaScript-rendered form, you need to add a hidden input
with name="form-name"
to the returned form elements. Here’s an example:
return (
<form
data-netlify="true"
name="pizzaOrder"
method="post"
onSubmit={handleSubmit}
>
<input type="hidden" name="form-name" value="pizzaOrder" />
<label>
What order did the pizza give to the pineapple?
<input name="order" type="text" onChange={handleChange} />
</label>
<input type="submit" />
</form>
);
In the code sample above, a handleChange
function updates the form’s state, which ultimately gets sent in a POST request to Netlify.
By default, when visitors complete a form, they are redirected to a page with a generically styled success message with a link back to the form page.
You can replace the default success page with a custom page you create by adding an action
attribute to the <form>
tag, entering the path of your custom page (like "/pages/success"
) as the value. The path must be relative to the site root, starting with a /
. Here’s an example:
<form
name="contact"
action="/pages/success"
method="POST"
data-netlify="true"
></form>
If you submit your form using AJAX, reference this Gatsby-specific example of how to set a custom success page.
If you use AJAX to submit the form, you can substitute an alert instead of redirecting to a generic or custom page. Here’s an example for an HTML form:
const handleSubmit = (event) => {
event.preventDefault();
const myForm = event.target;
const formData = new FormData(myForm);
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams(formData).toString(),
})
.then(() => alert("Thank you for your submission"))
.catch((error) => alert(error));
};
document
.querySelector("form")
.addEventListener("submit", handleSubmit);
Netlify Forms can receive files uploaded with form submissions. To do this, add an input with type="file"
to any form. Although most browsers will detect the encoding automatically, you can optionally include enctype="multipart/form-data"
in the <form>
tag,
Here’s a sample HTML form with a file upload field:
<form name="fileForm" enctype="multipart/form-data" data-netlify="true">
<p>
<label>
<span>Name:</span>
<input name="name" type="text"/>
</label>
</p>
<p>
<label>
<span>Add file:</span>
<input name="file" type="file"/>
</label>
</p>
<button>Submit</button>
</form>
<p class="result"></p>
Forms that accept file uploads that contain personally identifiable information (PII) require additional security configuration. We recommend using the Very Good Security integration for this type of secure form upload.
Keep the following considerations in mind when working with file uploads in forms.
When submitting a form with a file upload, including a Content-Type
header is not recommended. The browser should detect and set the Content-Type
automatically.
Here’s an AJAX form submission code sample using the fetch
API for the above HTML form with file upload:
document.forms.fileForm.addEventListener("submit", (event) => {
event.preventDefault();
const result = document.querySelector(".result");
fetch("/", {
body: new FormData(event.target),
method: "POST",
})
.then(() => {
result.innerText = "Success";
})
.catch((error) => {
result.innerText = `Failed: ${error}`;
});
});
Recommended for you: Functions
Use serverless functions to run on-demand, server-side code without having to manage a dedicated server.
Forms: Serverless Functions Integration
Forms: Serverless Functions Integration
Forms: Custom reCAPTCHA 2 with your own settings
Your feedback helps us improve our docs.