|
58 | 58 | triggerToast('Please enter a valid email address', 'error'); |
59 | 59 | return; |
60 | 60 | } |
| 61 | + window.grecaptcha = window.grecaptcha || {}; |
| 62 | +
|
| 63 | + const recaptchaResponse = window.document.getElementById('recaptchaResponse').value; |
| 64 | + if (!recaptchaResponse) { |
| 65 | + triggerToast('Please complete the ReCAPTCHA', 'error'); |
| 66 | + return; |
| 67 | + } |
61 | 68 | const response = await fetch(formSpree, { |
62 | 69 | method: 'POST', |
63 | 70 | body: JSON.stringify({ |
64 | 71 | firstname, |
65 | 72 | lastname, |
66 | 73 | email, |
67 | 74 | phone, |
68 | | - message |
| 75 | + message, |
| 76 | + 'g-recaptcha-response': recaptchaResponse |
69 | 77 | }), |
70 | 78 | headers: { |
71 | 79 | Accept: 'application/json' |
|
85 | 93 | } |
86 | 94 | } catch (error) { |
87 | 95 | triggerToast('Oops! There was a problem submitting your form', 'error'); |
| 96 | + } finally { |
| 97 | + if (window.grecaptcha) { |
| 98 | + window.grecaptcha.reset(); |
| 99 | + } |
88 | 100 | } |
89 | 101 | } |
90 | 102 | </script> |
91 | 103 |
|
92 | 104 | <svelte:head> |
93 | | - {#if env !== 'development'} |
94 | | - <script src="https://www.google.com/recaptcha/api.js" async defer></script> |
| 105 | + {#if recaptchaSiteKey && env !== 'development'} |
| 106 | + <script src="https://www.google.com/recaptcha/api.js"></script> |
| 107 | + <script> |
| 108 | + function recaptchaCallback(token) { |
| 109 | + window.document.getElementById('recaptchaResponse').value = token; |
| 110 | + } |
| 111 | + </script> |
95 | 112 | {/if} |
96 | 113 | </svelte:head> |
97 | 114 | <section id={Section.Contact} class="px-3 py-5 rounded-none lg:py-10 lg:px-5 card bg-surface-400"> |
|
184 | 201 | /> |
185 | 202 | </label> |
186 | 203 | {#if recaptchaSiteKey && env !== 'development'} |
187 | | - <div class="g-recaptcha" data-sitekey={recaptchaSiteKey}></div> |
| 204 | + <div |
| 205 | + class="g-recaptcha" |
| 206 | + data-sitekey={recaptchaSiteKey} |
| 207 | + data-callback="recaptchaCallback" |
| 208 | + ></div> |
| 209 | + <input id="recaptchaResponse" name="recaptchaResponse" type="hidden" /> |
188 | 210 | {/if} |
189 | 211 | <div class="mx-2 mt-2 mb-6 text-white bg-blue-500 rounded-xl md:justify-self-end btn"> |
190 | 212 | <button type="submit"> Send message </button> |
|
0 commit comments