Skip to content

Commit af021a1

Browse files
committed
Added google captcha
1 parent 78c0437 commit af021a1

File tree

5 files changed

+183
-5
lines changed

5 files changed

+183
-5
lines changed

.env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
NEXT_PUBLIC_EMAILJS_SERVICE_ID =
22
NEXT_PUBLIC_EMAILJS_TEMPLATE_ID =
3-
NEXT_PUBLIC_EMAILJS_PUBLIC_KEY =
3+
NEXT_PUBLIC_EMAILJS_PUBLIC_KEY =
4+
NEXT_PUBLIC_GTM =
5+
NEXT_PUBLIC_APP_URL = "http://127.0.0.1:3000"
6+
NEXT_PUBLIC_RECAPTCHA_SECRET_KEY =
7+
NEXT_PUBLIC_RECAPTCHA_SITE_KEY =

app/api/google/route.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import axios from "axios";
2+
import { NextResponse } from "next/server";
3+
4+
export async function POST(request) {
5+
const reqBody = await request.json();
6+
const secret_key = process.env.NEXT_PUBLIC_RECAPTCHA_SECRET_KEY;
7+
8+
try {
9+
const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secret_key}&response=${reqBody.token}`;
10+
11+
const res = await axios.post(url);
12+
if (res.data.success) {
13+
return NextResponse.json({
14+
message: "Captcha verification success!!",
15+
success: true,
16+
})
17+
};
18+
19+
return NextResponse.json({
20+
error: "Captcha verification failed!",
21+
success: false,
22+
}, { status: 500 });
23+
} catch (error) {
24+
return NextResponse.json({
25+
error: "Captcha verification failed!",
26+
success: false,
27+
}, { status: 500 });
28+
}
29+
}

app/components/homepage/contact/contact-form.jsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// @flow strict
33
import { isValidEmail } from '@/utils/check-email';
44
import emailjs from '@emailjs/browser';
5+
import axios from 'axios';
56
import { useState } from 'react';
7+
import ReCAPTCHA from 'react-google-recaptcha';
68
import { TbMailForward } from "react-icons/tb";
79
import { toast } from 'react-toastify';
810

@@ -12,6 +14,7 @@ function ContactForm() {
1214
email: '',
1315
message: '',
1416
});
17+
const [captcha, setCaptcha] = useState(null);
1518
const [error, setError] = useState({
1619
email: false,
1720
required: false,
@@ -24,6 +27,21 @@ function ContactForm() {
2427
};
2528

2629
const handleSendMail = async (e) => {
30+
if (!captcha) {
31+
toast.error('Please complete the captcha!');
32+
return;
33+
} else {
34+
const res = await axios.post(`${process.env.NEXT_PUBLIC_APP_URL}/api/google`, {
35+
token: captcha
36+
});
37+
38+
setCaptcha(null);
39+
if (!res.data.success) {
40+
toast.error('Captcha verification failed!');
41+
return;
42+
};
43+
};
44+
2745
e.preventDefault();
2846
if (!input.email || !input.message || !input.name) {
2947
setError({ ...error, required: true });
@@ -109,6 +127,10 @@ function ContactForm() {
109127
value={input.message}
110128
/>
111129
</div>
130+
<ReCAPTCHA
131+
sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}
132+
onChange={(code) => setCaptcha(code)}
133+
/>
112134
<div className="flex flex-col items-center gap-2">
113135
{error.required &&
114136
<p className="text-sm text-red-400">

package-lock.json

Lines changed: 125 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
"dependencies": {
1313
"@emailjs/browser": "^4.3.1",
1414
"@next/third-parties": "^14.1.3",
15+
"axios": "^1.6.8",
1516
"lottie-react": "^2.4.0",
1617
"next": "^14.1.3",
1718
"react": "latest",
1819
"react-dom": "latest",
1920
"react-fast-marquee": "^1.6.2",
21+
"react-google-recaptcha": "^3.1.0",
2022
"react-icons": "^4.11.0",
2123
"react-toastify": "^10.0.4"
2224
},

0 commit comments

Comments
 (0)