Progressively Enhancing a Netlify Form
Posted on
I currently host most of my websites on Netlify, and I have a pain point with the way they handle form submissions. After submitting a form and landing on the "success" page (either their default one or a custom one), refreshing that page will re-submit the form, creating a duplicate entry on the back-end. This is an age-old problem, and is solved very easily using the post-redirect-get workflow. However, Netlify does not implement post-redirect-get, and based on the discussion in this support article, they do not intend to.
I have a client who has complained about receiving too many duplicate form submissions, and I think it's an issue worth solving. Since I don't control Netlify's backend, I'll have to find a front-end solution.
The ideal solution is to submit the form with JavaScript using an XHR or fetch request. That way, refreshing the page has no effect on form submissions. However, then the form will only work when JavaScript is available, and there are many reasons why JavaScript might not be available. This is why I really prefer using the browser's built-in form submission system instead of relying on JavaScript.
Fortunately, it is really easy to progressively enhance forms to get the best of both worlds. All you need to do is set the form up like a normal form, and it will work that way when JavaScript is disabled. Then, when JavaScript is enabled, you can intercept the submit event and send the data yourself.
document.querySelector('form').addEventListener('submit', (event) => {
event.preventDefault()
fetch(event.target.action, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(new FormData(event.target)).toString()
})
.then(() => {
// handle success
})
.catch(() => {
// handle errors
})
})
Netlify's form setup documentation has an example of how to set this up. If your form has a file input, follow this example instead.
I love when progressive enhancement is this simple!