Let’s start by explaining things a bit. GatsbyJS is blazing fast. Maybe you’ve seen that when you’ve entered this site. Why? For many reasons but one of them is that it generates a Static Site. You are now reading a post on such a site.
It’s a site that is prebuild, already made, packed, awaiting to be send to client with a first request. It’s not build when user makes a request to the server.
Imagine you click on link to a forum page.
Each time you click the website can be different because it changes depending on other users’ input. Even if it’s a Django blog with only you as a user - the mechanism is the same.
Then how can I have a blog on Static Site? Simply by not having a database with posts. All the posts I’ve written are being shipped to you. There are no additional data packages with blog content when you surf my page. All the data is in your browser already.
So how can you write me a message or comment this post? Well, in your browser, right now (for example if you open Developer Tools) there is JavaScript code that can send your data to specific routes. Those routes lead to Netlify which are places with servers and databases. Those servers are thousands of miles away from you so each time you want to write a comment or send me a message you need to make a request. That’s why it takes seconds or minutes from the moment you send to the moment I recieve a notification. That’s why you can switch off your internet and continue navigating to different posts - all the data is in your browser already!
All the contrary information on the internet make it so confusing when it’s so simple. In order to make them work, the simplest thing you need is this:
(That is TypeScript file so *.TSX):
const SomeForm: React.SFC<{}> = () => {
return (
<Formik
initialValues={
"form-name": "Contact Me Form",
someInputField: ""}
render={({ }: FormikProps<MyFormValues>) => (
<Form name="Contact Me Form" method="post" data-netlify="true">
<input
type="hidden"
name="form-name"
value="Contact Me Form" />
<input
type="text"
name="someInputField"
/>
<button title="Submit" type="submit" />
</Form>
)}
/>
)
}
This is stripped code that has data neccessary for Netlify forms to work. To see complete code scroll down, but let’s start explaining.
First Formik component with initialValues. You need “form-name” that’s value will correspond with Form’s name and input’s value.
<Formik initialValues={ "form-name": "Contact Me Form", someInputField: ""}
Secondly you need form with name corresponding to form-name on Formik and to value on hidden input. Also you need to enable Netlify bot here by data-netlify=“true”.
<form name="Contact Me Form" method="post" data-netlify="true"></form>
Create hidden input that will allow netlify’s bot connect your form’s data with Formik values that are sent onSubmit.
<input type="hidden" name="form-name" value="Contact Me Form" />
And finally the last step is sending the data to a root URL. You can do that with onSubmit function:
<Formik
initialValues={
"form-name": "Contact Me Form",
someInputField: ""}
}
onSubmit={(
values: MyFormValues,
) => {
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({
"form-name": "formik",
...values,
}),
})
.then(succ => console.log(succ))
.catch(error => console.log(error))
}}
(this is incomplete! for full code scroll down.)
function encode(data) {
return Object.keys(data)
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
.join('&')
}
This is the key to make Netlify forms work. Once you do that and deploy, you will be able to use that form (it doesn’t work locally!).
There is more options like reCatcha, or filtering SPAM that netlify provides. You don’t need form’s action or honeypots to make sending forms possible.
Add “bot-field”: "", to initial values
<Formik initialValues={{"bot-field": "", "form-name": "Contact Me Form",
someInputField: ""}}
and add data-netlify-honeypot=“bot-field” to Form
<form
name="Contact Me Form"
method="post"
data-netlify="true"
data-netlify-honeypot="bot-field"
></form>
import { navigate } from 'gatsby'
<Formik
initialValues={
"form-name": "Contact Me Form",
someInputField: ""}
}
onSubmit={(
values: MyFormValues,
) => {
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({
"form-name": "formik",
...values,
}),
})
.then(succ => navigate("/thanks"))
.catch(error => alert(error))
}}
import * as React from 'react'
import { Formik, FormikProps, Form } from 'formik'
import { navigate } from 'gatsby'
interface FormValidValues {
message: string
}
function encode(data) {
return Object.keys(data)
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
.join('&')
}
const Contact: React.SFC<{}> = () => {
return (
<Formik
initialValues={{
'bot-field': '',
'form-name': 'contact',
message: '',
}}
onSubmit={(values: MyFormValues) => {
fetch('/', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: encode({
'form-name': 'formik',
...values,
}),
})
.then((succ) => navigate('/thanks'))
.catch((error) => console.log(error))
}}
render={({ handleChange, values }: FormikProps<FormValidValues>) => (
<Form
name="contact"
method="post"
data-netlify-honeypot="bot-field"
data-netlify="true"
>
<Input type="hidden" name="form-name" value="contact" />
<Input
type="text"
name="message"
value={`${values.firstName}`}
onChange={handleChange}
label="Name"
/>
<Button title="Submit" type="submit" />
</Form>
)}
/>
)
}
export default Contact
Did you make any mistakes when using REACT or you’ve seen one here? Tell me about your insights. Leave a comment with You are most welcome to see more posts of this type just go to home page