Web3Forms
Search…
React JS
React contact form example using react-hook-form plugin
Here's a sample React Contact Form built with react-hook-form plugin. See Plugin docs here.
This example uses TailwindCSS for styling. You may use your own if needed.
1
import React from "react";
2
import { useForm, useWatch } from "react-hook-form";
3
4
export default function ContactForm() {
5
const {
6
register,
7
handleSubmit,
8
reset,
9
control,
10
formState: { errors, isSubmitSuccessful, isSubmitting },
11
} = useForm({
12
mode: "onTouched",
13
});
14
const [isSuccess, setIsSuccess] = React.useState(false);
15
const [Message, setMessage] = React.useState("");
16
17
const userName = useWatch({ control, name: "name", defaultValue: "Someone" });
18
19
const onSubmit = async (data, e) => {
20
console.log(data);
21
await fetch("https://api.web3forms.com/submit", {
22
method: "POST",
23
headers: {
24
"Content-Type": "application/json",
25
Accept: "application/json",
26
},
27
body: JSON.stringify(data, null, 2),
28
})
29
.then(async (response) => {
30
let json = await response.json();
31
if (json.success) {
32
setIsSuccess(true);
33
setMessage(json.message);
34
e.target.reset();
35
reset();
36
} else {
37
setIsSuccess(false);
38
setMessage(json.message);
39
}
40
})
41
.catch((error) => {
42
setIsSuccess(false);
43
setMessage("Client Error. Please check the console.log for more info");
44
console.log(error);
45
});
46
};
47
48
return (
49
<>
50
<div className="w-full max-w-sm mx-auto my-5 border border-gray-100 rounded-md p-7">
51
{!isSubmitSuccessful && (
52
<form onSubmit={handleSubmit(onSubmit)}>
53
<input
54
type="hidden"
55
value="YOUR_ACCESS_KEY_HERE"
56
{...register("apikey")}
57
/>
58
<input
59
type="hidden"
60
value={`${userName} sent a message from Mission Control`}
61
{...register("subject")}
62
/>
63
<input
64
type="hidden"
65
value="Mission Control"
66
{...register("from_name")}
67
/>
68
<input
69
type="checkbox"
70
id=""
71
className="hidden"
72
style={{ display: "none" }}
73
{...register("botcheck")}></input>
74
75
<div className="mb-5">
76
<input
77
type="text"
78
placeholder="Full Name"
79
autoComplete="false"
80
className={`w-full px-4 py-3 border-2 rounded-md outline-none focus:ring-4 ${
81
errors.name
82
? "border-red-600 focus:border-red-600 ring-red-100"
83
: "border-gray-300 focus:border-indigo-600 ring-indigo-100"
84
}`}
85
{...register("name", {
86
required: "Full name is required",
87
maxLength: 80,
88
})}
89
/>
90
{errors.name && (
91
<div className="mt-1 text-red-600">
92
<small>{errors.name.message}</small>
93
</div>
94
)}
95
</div>
96
97
<div className="mb-5">
98
<label htmlFor="email_address" className="sr-only">
99
Email Address
100
</label>
101
<input
102
id="email_address"
103
type="email"
104
placeholder="Email Address"
105
name="email"
106
autoComplete="false"
107
className={`w-full px-4 py-3 border-2 rounded-md outline-none focus:ring-4 ${
108
errors.email
109
? "border-red-600 focus:border-red-600 ring-red-100"
110
: "border-gray-300 focus:border-indigo-600 ring-indigo-100"
111
}`}
112
{...register("email", {
113
required: "Enter your email",
114
pattern: {
115
value: /^\[email protected]\S+$/i,
116
message: "Please enter a valid email",
117
},
118
})}
119
/>
120
{errors.email && (
121
<div className="mt-1 text-red-600">
122
<small>{errors.email.message}</small>
123
</div>
124
)}
125
</div>
126
127
<div className="mb-3">
128
<textarea
129
name="message"
130
placeholder="Your Message"
131
className={`w-full px-4 py-3 border-2 rounded-md outline-none h-36 focus:ring-4 ${
132
errors.message
133
? "border-red-600 focus:border-red-600 ring-red-100"
134
: "border-gray-300 focus:border-indigo-600 ring-indigo-100"
135
}`}
136
{...register("message", { required: "Enter your Message" })}
137
/>
138
{errors.message && (
139
<div className="mt-1 text-red-600">
140
{" "}
141
<small>{errors.message.message}</small>
142
</div>
143
)}
144
</div>
145
146
<button
147
type="submit"
148
className="w-full py-4 text-white transition-colors bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none focus:ring-offset-2 focus:ring focus:ring-indigo-200 px-7 umami--click--contact-submit">
149
{isSubmitting ? (
150
<svg
151
className="w-5 h-5 mx-auto text-white animate-spin"
152
xmlns="http://www.w3.org/2000/svg"
153
fill="none"
154
viewBox="0 0 24 24">
155
<circle
156
className="opacity-25"
157
cx="12"
158
cy="12"
159
r="10"
160
stroke="currentColor"
161
strokeWidth="4"></circle>
162
<path
163
className="opacity-75"
164
fill="currentColor"
165
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
166
</svg>
167
) : (
168
"Send Message"
169
)}
170
</button>
171
</form>
172
)}
173
{isSubmitSuccessful && isSuccess && (
174
<>
175
<div className="flex flex-col items-center justify-center text-center text-white rounded-md">
176
<svg
177
width="100"
178
height="100"
179
className="text-green-300"
180
viewBox="0 0 100 100"
181
fill="none"
182
xmlns="http://www.w3.org/2000/svg">
183
<path
184
d="M26.6666 50L46.6666 66.6667L73.3333 33.3333M50 96.6667C43.8716 96.6667 37.8033 95.4596 32.1414 93.1144C26.4796 90.7692 21.3351 87.3317 17.0017 82.9983C12.6683 78.6649 9.23082 73.5204 6.8856 67.8586C4.54038 62.1967 3.33331 56.1283 3.33331 50C3.33331 43.8716 4.54038 37.8033 6.8856 32.1414C9.23082 26.4796 12.6683 21.3351 17.0017 17.0017C21.3351 12.6683 26.4796 9.23084 32.1414 6.88562C37.8033 4.5404 43.8716 3.33333 50 3.33333C62.3767 3.33333 74.2466 8.24998 82.9983 17.0017C91.75 25.7534 96.6666 37.6232 96.6666 50C96.6666 62.3768 91.75 74.2466 82.9983 82.9983C74.2466 91.75 62.3767 96.6667 50 96.6667Z"
185
stroke="currentColor"
186
strokeWidth="3"
187
/>
188
</svg>
189
<h3 className="py-5 text-2xl text-green-500">Success</h3>
190
<p className="text-gray-700 md:px-3">{Message}</p>
191
<button
192
className="mt-6 text-indigo-600 focus:outline-none"
193
onClick={() => reset()}>
194
Go back
195
</button>
196
</div>
197
</>
198
)}
199
200
{isSubmitSuccessful && !isSuccess && (
201
<div className="flex flex-col items-center justify-center text-center text-white rounded-md">
202
<svg
203
width="97"
204
height="97"
205
viewBox="0 0 97 97"
206
className="text-red-400"
207
fill="none"
208
xmlns="http://www.w3.org/2000/svg">
209
<path
210
d="M27.9995 69C43.6205 53.379 52.3786 44.621 67.9995 29M26.8077 29L67.9995 69M48.2189 95C42.0906 95 36.0222 93.7929 30.3604 91.4477C24.6985 89.1025 19.554 85.6651 15.2206 81.3316C10.8872 76.9982 7.44975 71.8538 5.10454 66.1919C2.75932 60.53 1.55225 54.4617 1.55225 48.3333C1.55225 42.205 2.75932 36.1366 5.10454 30.4748C7.44975 24.8129 10.8872 19.6684 15.2206 15.335C19.554 11.0016 24.6985 7.56418 30.3604 5.21896C36.0222 2.87374 42.0906 1.66667 48.2189 1.66667C60.5957 1.66667 72.4655 6.58333 81.2172 15.335C89.9689 24.0867 94.8856 35.9566 94.8856 48.3333C94.8856 60.7101 89.9689 72.58 81.2172 81.3316C72.4655 90.0833 60.5957 95 48.2189 95Z"
211
stroke="CurrentColor"
212
strokeWidth="3"
213
/>
214
</svg>
215
216
<h3 className="text-2xl text-red-400 py-7">
217
Oops, Something went wrong!
218
</h3>
219
<p className="text-gray-300 md:px-3">{Message}</p>
220
<button className="mt-5 focus:outline-none" onClick={() => reset()}>
221
Try Again
222
</button>
223
</div>
224
)}
225
</div>
226
<p
227
class="text-center text-sm
228
">
229
<a
230
href="https://web3forms.com/"
231
target="_blank"
232
rel="noopener"
233
className="text-indigo-500">
234
Forms by Web3Froms
235
</a>
236
</p>
237
</>
238
);
239
}
Copied!
Last modified 5mo ago
Copy link