This repo was created to test and document how to get Netlify Forms working with Formik in a Create React App build and add ReCaptcha if desired.
Netlify Forms is a super cool (and free) feature for sites hosted on the Netlify platform.
Formik is a great library that "removes the tears" from form creation in React.
The problem is that forms rendered via React don't work out of the box with Netlify forms.
โ๏ธ This readme is a work in progress as I work toward a solution. Don't take anyting literally until this comment is removed.
You need to add a hidden HTML form that mimics the fields in your Formik form to the /public/index.html file in the public directory, or Netlify forms won't work.
โ๏ธ Note that static site generators like Gatsby and Hugo are different beasts and require a different solution than would a CRA build. Documentation here is soley pertinent to CRA.
This is a very informative article; however--for me, at least--it took a while to realize that there needs to be a mirror HTML form in /public/index.html of the form being rendered by React.
Reading this can be helpful or send you off on a wild goose-chase or two.
- Create React App
- Axios ( with qs ) for the post
- Bootswatch ( Simplex ) for CSS
- Formik
Without extra setup, submitting a React form when hosted on Netlify will return a 404 error.
The 404 error can be a bit misleading because, when you look at the code, the form is there. It should be found. So what's happening?!
The reason is that Netlify's form-bots can't see JavaScript rendered form code.
So in order to get this working, you need to do a bit of extra work.
Add the following form block just below the initial <body> element tag in /public/index.html:
<form data-netlify="true" hidden name="contact" netlify-honeypot="bot-field"> <input type="text" name="username" /> <input type="email" name="email" /> <input name="bot-field" type="hidden" /> </form>โ๏ธ This is obviously just an example, so make sure that there is one-to-one match here, whereby each input corresponds with a respective input element/Field component in your Formik form.
a) Add a bot-field and form-name field to initialValues of the Formik form:
<Formik initialValues={{ "bot-field": "", "form-name": "contact", email: "", username: "" }}While the honeypot is a novel concept, it's not really effective against spam bots, so you check out the section on adding reCaptcha, which is a much more robust solution.
:pointup: In February 2019, Netflify announced that all form submissions will be filtered for spam, using Akismet. _Huzzah huzzah!
b) Add those (hidden) fields to the Formik form itself:
<Field type="hidden" name="form-name" /> <Field type="hidden" name="bot-field" />โ๏ธ The relevant code to see how this works can be found in
/public/index.htmlandFormikForm.jswithin this repo.
Use a library to add Recaptcha (e.g. reaptcha) and don't add anything related to reCaptcha to the /public/index.html file.
โ๏ธ reCaptcha is notoriously easy to mistype, and
Reaptchaadds another nuance to the pot. I've used abbreviations in variables to help avoid issues around that.
There are a lot of libraries out there for adding reCaptcha to a React site. After a bit of trial and error, I settled on reaptcha.
Most reCaptcha libraries are not especially clear, IMHO, with regards to how to get the end-to-end solution working.
There's s few steps involved to get things done with Netlify Forms.
Reaptcha has a built in function, onLoad, which is set as an attribute on the Reaptcha in the FormikForm.js file
In this example, I use a React effect hook to watch for changes to a React state hook value (rcLoaded), which gets updated when reCaptcha eventually loads after mount.
Once reCaptcha is loaded, reCaptcha gets executed. The reason for running execute() is for the support of reCaptcha v2 invisible, which I have set via the size attribute on the Reaptcha component.
Once it's executed, it gets verified (or not), and the reCaptcha response (token) is placed into state in a React state hook, rcResponse.
This state value is injected into the data object, along with the other form field data in the onSubmit function of the Formik form.
Reaptcha has a built in function, onVerify, which is set as an attribute on the Reaptcha component in the FormikForm.js file
Once reCaptcha has been loaden, onVerify() will run and return the reCaptcha response (in the form of a token).
The onVerify function in FormikForm.js (not the Reaptcha one) populates the React hook state value rcResponse.
rcResponse gets injected into data when the form is submitted and it's value is assigned to the key, g-recaptcha-response.