Skip to content

Formik Newsletter

In this example we will create a simple newsletter signup form with Formik. It only includes an email field which is validated client-side (note: client-side validation is not safe, thus you might see data other than emails in Netlify).

In order to use Formik’s handlers, we use a hook-based approach which allows us to link Formik’s submit handler with react-netlify-forms one. Therefore, we have to import useNetlifyForm and useFormik. Furthermore, we have to use NetlifyFormProvider and NetlifyFormComponent to render the form with context ourselves:

import {
useNetlifyForm,
NetlifyFormProvider,
NetlifyFormComponent,
Honeypot
} from 'react-netlify-forms'
import { useFormik } from 'formik'

First, we get all Netlify Forms functions through useNetlifyForm and then setup Formik with useFormik. We supply the former submit handler to Formik’s onSubmit to link them which means that the form is validated by Formik and then values are sent to the server by react-netlify-forms.

NetlifyFormProvider enables us to create the corresponding context by passing Netlify functions through props. In the following, the context is consumed by NetlifyFormComponent to render a form with all neccessary attributes.

Instead of managing form state through react-netlify-forms, it is now controlled by Formik with e.g. handleChange.

Last but not least, note that we defined validation logic in Formik as a simple check whether input is filled and it matches a regular expression describing emails.

See the full example in action here:

function NewsletterForm() {
const netlify = useNetlifyForm({
name: 'Formik',
action: '/thanks',
honeypotName: 'bot-field',
onSuccess: (response, context) => {
console.log('Successfully sent form data to Netlify Server')
}
})
const {
handleSubmit,
handleChange,
handleBlur,
touched,
errors,
values
} = useFormik({
initialValues: { email: '' },
onSubmit: (values) => netlify.handleSubmit(null, values),
validate: (values) => {
const errors = {}
if (!values.email) {
errors.email = 'Email is required'
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
) {
errors.email = 'Invalid email address'
}
return errors
}
})
return (
<NetlifyFormProvider {...netlify}>
<NetlifyFormComponent onSubmit={handleSubmit}>
<Honeypot />
{netlify.success && (
<p>
Thanks for contacting us!
</p>
)}
{netlify.error && (
<p>
Sorry, we could not reach servers. Because it only works on Netlify,
our GitHub demo does not provide a response.
</p>
)}
<div>
<label htmlFor='email'>
Email:
</label>
<input
type='email'
name='email'
id='email'
onChange={handleChange}
onBlur={handleBlur}
value={values.email}
/>
{touched.email && errors.email ? (
<div>{errors.email}</div>
) : null}
</div>
<div>
<button type='submit'>
Submit
</button>
<button type='reset'>
Reset
</button>
</div>
</NetlifyFormComponent>
</NetlifyFormProvider>
)
}