mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-25 02:08:50 +02:00
Add captcha on forms
This commit is contained in:
16
src/components/Captcha/Captcha.astro
Normal file
16
src/components/Captcha/Captcha.astro
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
<script
|
||||||
|
src='https://www.google.com/recaptcha/api.js?onload=onCaptchaLoad&render=explicit'
|
||||||
|
async
|
||||||
|
defer
|
||||||
|
slot='after-header'
|
||||||
|
></script>
|
||||||
|
|
||||||
|
<script src='./captcha.js'></script>
|
||||||
|
|
||||||
|
<!-- Captcha form start -->
|
||||||
|
<div class='recaptcha-field mb-2'></div>
|
||||||
|
<input type='hidden' name='g-recaptcha-response' class='recaptcha-response' />
|
||||||
|
<!-- Catpcha form end -->
|
77
src/components/Captcha/captcha.js
Normal file
77
src/components/Captcha/captcha.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
class Captcha {
|
||||||
|
constructor() {
|
||||||
|
this.onDOMLoaded = this.onDOMLoaded.bind(this);
|
||||||
|
this.bindValidation = this.bindValidation.bind(this);
|
||||||
|
this.validateCaptchaBeforeSubmit =
|
||||||
|
this.validateCaptchaBeforeSubmit.bind(this);
|
||||||
|
this.onCaptchaLoad = this.onCaptchaLoad.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
validateCaptchaBeforeSubmit(e) {
|
||||||
|
const target = e.target;
|
||||||
|
const captchaField = target.querySelector('.recaptcha-field');
|
||||||
|
|
||||||
|
if (captchaField) {
|
||||||
|
const captchaId = captchaField.dataset.recaptchaId;
|
||||||
|
const captchaResponse = window.grecaptcha.getResponse(captchaId);
|
||||||
|
|
||||||
|
// If valid captcha is not present, prevent form submission
|
||||||
|
if (!captchaResponse) {
|
||||||
|
e.preventDefault();
|
||||||
|
alert('Please verify that you are human first');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.querySelector('.recaptcha-response').value = captchaResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.closest('.modal').classList.add('hidden');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bindValidation() {
|
||||||
|
const forms = document.querySelectorAll('.validate-captcha-form');
|
||||||
|
|
||||||
|
forms.forEach((form) => {
|
||||||
|
form.addEventListener('submit', this.validateCaptchaBeforeSubmit);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onCaptchaLoad() {
|
||||||
|
if (!window.grecaptcha) {
|
||||||
|
console.warn('window.grecaptcha is not defined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recaptchaFields = document.querySelectorAll('.recaptcha-field');
|
||||||
|
|
||||||
|
console.log(recaptchaFields);
|
||||||
|
|
||||||
|
// render recaptcha on fields
|
||||||
|
recaptchaFields.forEach((field) => {
|
||||||
|
// If captcha already rendered for this field
|
||||||
|
if (field.hasAttribute('data-recaptcha-id')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderedId = window.grecaptcha.render(field, {
|
||||||
|
sitekey: '6Ldn2YsjAAAAABlUxNxukAuDAUIuZIhO0hRVxzJW',
|
||||||
|
});
|
||||||
|
|
||||||
|
field.setAttribute('data-recaptcha-id', renderedId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onDOMLoaded() {
|
||||||
|
this.bindValidation();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
window.addEventListener('DOMContentLoaded', this.onDOMLoaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const captcha = new Captcha();
|
||||||
|
captcha.init();
|
||||||
|
|
||||||
|
window.onCaptchaLoad = captcha.onCaptchaLoad;
|
@@ -1,45 +1,39 @@
|
|||||||
---
|
---
|
||||||
import Popup from "./Popup/Popup.astro";
|
import Popup from './Popup/Popup.astro';
|
||||||
|
import Captcha from './Captcha/Captcha.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<Popup
|
<Popup
|
||||||
id="download-popup"
|
id='download-popup'
|
||||||
title="Download Roadmap"
|
title='Download Roadmap'
|
||||||
subtitle="Enter your email below to receive the download link."
|
subtitle='Enter your email below to receive the download link.'
|
||||||
>
|
>
|
||||||
<form
|
<form
|
||||||
action="https://newsletter.roadmap.sh/subscribe"
|
action='https://newsletter.roadmap.sh/subscribe'
|
||||||
method="POST"
|
method='POST'
|
||||||
accept-charset="utf-8"
|
accept-charset='utf-8'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
class="validate-captcha-form"
|
class='validate-captcha-form'
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type='email'
|
||||||
name="email"
|
name='email'
|
||||||
id="email"
|
id='email'
|
||||||
required
|
required
|
||||||
autofocus
|
autofocus
|
||||||
class="w-full rounded-md border text-md py-2.5 px-3 mb-2"
|
class='w-full rounded-md border text-md py-2.5 px-3 mb-2'
|
||||||
placeholder="Enter your Email"
|
placeholder='Enter your Email'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- {# Captcha Form Start #} -->
|
<Captcha />
|
||||||
<div class="recaptcha-field mb-2"></div>
|
|
||||||
<input
|
|
||||||
type="hidden"
|
|
||||||
name="g-recaptcha-response"
|
|
||||||
class="recaptcha-response"
|
|
||||||
/>
|
|
||||||
<!-- {# Captcha Form End #} -->
|
|
||||||
|
|
||||||
<input type="hidden" name="list" value="tTqz1w7nexY3cWDpLnI88Q" />
|
<input type='hidden' name='list' value='tTqz1w7nexY3cWDpLnI88Q' />
|
||||||
<input type="hidden" name="subform" value="yes" />
|
<input type='hidden' name='subform' value='yes' />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type='submit'
|
||||||
name="submit"
|
name='submit'
|
||||||
class="text-white bg-gradient-to-r from-amber-700 to-blue-800 hover:from-amber-800 hover:to-blue-900 font-regular rounded-md text-md px-5 py-2.5 w-full text-center mr-2"
|
class='text-white bg-gradient-to-r from-amber-700 to-blue-800 hover:from-amber-800 hover:to-blue-900 font-regular rounded-md text-md px-5 py-2.5 w-full text-center mr-2'
|
||||||
>
|
>
|
||||||
Send Link
|
Send Link
|
||||||
</button>
|
</button>
|
||||||
|
@@ -1,44 +1,38 @@
|
|||||||
---
|
---
|
||||||
import Popup from "./Popup/Popup.astro";
|
import Popup from './Popup/Popup.astro';
|
||||||
|
import Captcha from './Captcha/Captcha.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<Popup
|
<Popup
|
||||||
id="subscribe-popup"
|
id='subscribe-popup'
|
||||||
title="Subscribe"
|
title='Subscribe'
|
||||||
subtitle="Enter your email below to receive updates."
|
subtitle='Enter your email below to receive updates.'
|
||||||
>
|
>
|
||||||
<form
|
<form
|
||||||
action="https://newsletter.roadmap.sh/subscribe"
|
action='https://newsletter.roadmap.sh/subscribe'
|
||||||
method="POST"
|
method='POST'
|
||||||
accept-charset="utf-8"
|
accept-charset='utf-8'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
class="validate-captcha-form"
|
class='validate-captcha-form'
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type='email'
|
||||||
name="email"
|
name='email'
|
||||||
required
|
required
|
||||||
autofocus
|
autofocus
|
||||||
class="w-full rounded-md border text-md py-2.5 px-3 mb-2"
|
class='w-full rounded-md border text-md py-2.5 px-3 mb-2'
|
||||||
placeholder="Enter your Email"
|
placeholder='Enter your Email'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Captcha Form Start -->
|
<Captcha />
|
||||||
<div class="recaptcha-field mb-2"></div>
|
|
||||||
<input
|
|
||||||
type="hidden"
|
|
||||||
name="g-recaptcha-response"
|
|
||||||
class="recaptcha-response"
|
|
||||||
/>
|
|
||||||
<!-- Captcha Form End -->
|
|
||||||
|
|
||||||
<input type="hidden" name="list" value="tTqz1w7nexY3cWDpLnI88Q" />
|
<input type='hidden' name='list' value='tTqz1w7nexY3cWDpLnI88Q' />
|
||||||
<input type="hidden" name="subform" value="yes" />
|
<input type='hidden' name='subform' value='yes' />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type='submit'
|
||||||
name="submit"
|
name='submit'
|
||||||
class="text-white bg-gradient-to-r from-amber-700 to-blue-800 hover:from-amber-800 hover:to-blue-900 font-regular rounded-md text-md px-5 py-2.5 w-full text-center mr-2"
|
class='text-white bg-gradient-to-r from-amber-700 to-blue-800 hover:from-amber-800 hover:to-blue-900 font-regular rounded-md text-md px-5 py-2.5 w-full text-center mr-2'
|
||||||
>
|
>
|
||||||
Subscribe
|
Subscribe
|
||||||
</button>
|
</button>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import Captcha from '../components/Captcha/Captcha.astro';
|
||||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -35,14 +36,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
|
|||||||
placeholder='Enter your email'
|
placeholder='Enter your email'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Captcha form start -->
|
<Captcha />
|
||||||
<div class='recaptcha-field mb-2'></div>
|
|
||||||
<input
|
|
||||||
type='hidden'
|
|
||||||
name='g-recaptcha-response'
|
|
||||||
class='recaptcha-response'
|
|
||||||
/>
|
|
||||||
<!-- Catpcha form end -->
|
|
||||||
|
|
||||||
<input type='hidden' name='list' value='tTqz1w7nexY3cWDpLnI88Q' />
|
<input type='hidden' name='list' value='tTqz1w7nexY3cWDpLnI88Q' />
|
||||||
<input type='hidden' name='subform' value='yes' />
|
<input type='hidden' name='subform' value='yes' />
|
||||||
|
Reference in New Issue
Block a user