> Portal Navigation:
>
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt
## Resource: Using reCAPTCHA to Protect Data Submission
## Article: Using reCAPTCHA to Protect Data Submission
## Article Link: https://dev.wix.com/docs/develop-websites/articles/code-tutorials/wix-editor-elements/using-re-captcha-to-protect-data-submission.md
## Article Content:
# Velo Tutorial: Using reCAPTCHA to Protect Data Submission
The [reCAPTCHA element](https://dev.wix.com/docs/velo/api-reference/$w/captcha/introduction.md) helps verify that site visitors are human before allowing actions like submitting data, logging in, or accessing private content. By adding it to your site, you can protect it from spam and automated abuse.
This tutorial demonstrates how to add CAPTCHA to secure custom form submissions and database entries by performing the following steps:
1. Create a custom mailing list form where visitors provide their name and email.
2. Use the reCAPTCHA element to require visitors to complete a CAPTCHA challenge before submitting their information.
3. When the challenge is successfully completed and the CAPTCHA is first verified on the frontend, authorize the CAPTCHA token in the backend to ensure the form was completed by a human.
4. Insert the validated data into a database collection if the token is valid. If the token fails validation or expires, reset the CAPTCHA and display an error message.
> **Notes:**
> * You can add CAPTCHA to [Wix Forms](https://support.wix.com/en/article/adding-captcha-to-your-wix-forms) and [Wix Signup & Login](https://support.wix.com/en/article/site-members-editing-the-signup-settings-for-the-default-and-custom-forms) forms without code.
> * To use CAPTCHA for data submission via a dataset, you must implement the submission using code. For example, use Wix Data APIs like [insert()](https://dev.wix.com/docs/velo/api-reference/wix-data/insert.md) or [save()](https://dev.wix.com/docs/velo/api-reference/wix-data/save.md) to handle the data operation and integrate CAPTCHA for protection.
> * In addition to adding CAPTCHA for security purposes, you may want to [validate visitor inputs](https://dev.wix.com/docs/develop-websites/articles/databases/wix-data/user-input/about-validating-user-input-with-code.md) to make sure the data is in the correct format.
## Step 1 | Add elements to the page
Add the following elements to the **Home** page:
* Input elements for visitors to provide their name and email.
* reCAPTCHA element to protect the data submission.
* A button to submit the data upon successful CAPTCHA verification.
* Text for displaying success and error messages.
## Step 2 | Create a database collection
Create a [database collection](https://support.wix.com/en/article/cms-formerly-content-manager-creating-a-collection) called **MailingList** to store the visitor's name and email after the CAPTCHA verification is successful. Add 2 text fields, `name` and `email`.
## Step 3 | Write the backend code
While frontend CAPTCHA verification ensures the site visitor successfully completes the challenge, backend validation prevents site visitors from spoofing or bypassing CAPTCHA. To ensure complete protection, you must implement [backend authorization](https://dev.wix.com/docs/velo/api-reference/wix-captcha-backend/authorize.md) to validate the CAPTCHA token securely:
1. Add a [web module](https://dev.wix.com/docs/develop-websites/articles/coding-with-velo/backend-code/web-modules/about-web-modules.md) named **submitHandler.web.js** to your backend code.
2. Use the following code to validate the CAPTCHA token and insert the data into the **MailingList** collection if the token is valid:
```javascript
import { Permissions, webMethod } from 'wix-web-module';
import wixCaptcha from 'wix-captcha-backend';
import wixData from 'wix-data';
export const processSubmission = webMethod(Permissions.Anyone, (submitRequestData) => {
return wixCaptcha.authorize(submitRequestData.token)
.then(() => {
return wixData.insert("MailingList", submitRequestData.data);
});
});
```
**Lines 1-3**: Import the `Permissions` enum and `webMethod` function from `wix-web-module`. Then import the modules you need to work with CAPTCHA in the backend and with data.
**Lines 5-6**: Create a web method with permissions for anyone to call it from the frontend.
**Lines 7-8**: Pass the web method a function that checks the token's authorization.
**Line 9**: Insert the data into the **MailingList** collection if the token is authorized.
## Step 4 | Write the page code
In your **Home** page, write the code for verifying the CAPTCHA in the frontend:
1. Import the backend function from your web module:
```javascript
import { processSubmission } from 'backend/submitHandler.web';
```
2. Set initial element states:
```javascript
$w.onReady(function () {
$w("#messageText").hide();
$w("#submitButton").disable();
});
```
**Lines 1-4**: To make sure site visitors complete a CAPTCHA challenge before being able to submit their entries, set the initial element states in the `onReady` function. Hide the text for displaying success and error messages upon submission, and disable the submit button.
2. Add the following code to enable the submit button when CAPTCHA verification is successful:
```javascript
$w("#captcha").onVerified(() => {
$w("#messageText").hide();
$w("#submitButton").enable();
});
```
**Line 1**: Add an `onVerified` event handler that runs when the CAPTCHA challenge is successfully completed and the CAPTCHA is verified.
**Line 2**: Hide any previous success or error messages.
**Line 3**: Enable the previously disabled submit button so the site visitor can complete the submission.
> **Note**
> When the CAPTCHA is verified, a CAPTCHA token is automatically generated. This token is used for authorization.
3. Write code to handle data submission and reset the CAPTCHA element if the process fails:
```javascript
$w("#submitButton").onClick(() => {
let submitRequestData = {
"token": $w("#captcha").token,
"data": {
"name": $w("#nameInput").value,
"email": $w("#emailInput").value
}
};
processSubmission(submitRequestData)
.then( () => {
resetCaptcha("Data successfully submitted");
})
.catch( () => {
resetCaptcha("Something went wrong. Redo the captcha challenge.");
});
});
function resetCaptcha(messageText) {
$w("#captcha").reset();
$w("#submitButton").disable();
$w("#messageText").text = messageText;
$w("#messageText").show();
}
```
**Line 1**: Add an event handler that runs when a site visitor clicks the submit button.
**Lines 2-7**: Prepare the submit request data. The request data includes the CAPTCHA token generated when the captcha was verified, and the data entered in the input elements.
**Line 10**: Call the `processSubmission` backend function with the prepared submit request data. The `processSubmission` function validates the token and inserts the data into the **MailingList** collection.
**Lines 12-24**: If authorization and data insertion are successful, display a success message and restart the CAPTCHA lifecycle for future submissions by resetting the reCAPTCHA element and disabling the submit button. If authorization or data insertion fail in the backend, restart the CAPTCHA lifecycle by resetting the reCAPTCHA element, disable the submit button, and display an error message instructing the site visitor to try again.
4. Show an error message if the CAPTCHA element loses connection with the provider:
```javascript
$w("#captcha").onError(() => {
$w("#messageText").text = "The reCAPTCHA element lost connection with the CAPTCHA provider. Try again later.";
$w("#messageText").show()
.then(() => {
$w("#messageText").hide("fade", {"delay": 10000});
});
});
```
**Lines 2-3**: If the reCAPTCHA element loses connection with the provider when the site visitor attempts to complete the CAPTCHA challenge, the reCAPTCHA element automatically resets. Set the message text to an error message asking the site visitor to try again later.
**Lines 4-5**: Show the message.
**Lines 6-8**: Hide the message after 10 seconds.
5. Disable the submit button if the CAPTCHA token expires:
```javascript
$w("#captcha").onTimeout(() => {
$w("#submitButton").disable();
});
```
**Lines 1-3**: If the submit does not occur within 120 seconds of completing the CAPTCHA challenge, the generated token expires. When the token expires, the reCAPTCHA element automatically resets and displays a message asking the site visitor to redo the challenge. In this case, disable the submit button in the `onTimeout` event handler.
### Example code
Here is the complete code for this example:
#### Page code
```javascript
import { processSubmission } from 'backend/submitHandler.web';
$w.onReady(function () {
$w("#messageText").hide();
$w("#submitButton").disable();
});
$w("#captcha").onVerified(() => {
$w("#messageText").hide();
$w("#submitButton").enable();
});
$w("#submitButton").onClick(() => {
let submitRequestData = {
"token": $w("#captcha").token,
"data": {
"name": $w("#nameInput").value,
"email": $w("#emailInput").value
}
};
processSubmission(submitRequestData)
.then( () => {
resetCaptcha("Data successfully submitted");
})
.catch( () => {
resetCaptcha("Something went wrong. Redo the captcha challenge.");
});
});
$w("#captcha").onError(() => {
$w("#messageText").text = "The reCAPTCHA element lost connection with the CAPTCHA provider. Try again later.";
$w("#messageText").show()
.then(() => {
$w("#messageText").hide("fade", {"delay": 10000});
});
});
$w("#captcha").onTimeout(() => {
$w("#submitButton").disable();
});
function resetCaptcha(messageText) {
$w("#captcha").reset();
$w("#submitButton").disable();
$w("#messageText").text = messageText;
$w("#messageText").show();
}
```
#### Backend code
```javascript
import { Permissions, webMethod } from 'wix-web-module';
import wixCaptcha from 'wix-captcha-backend';
import wixData from 'wix-data';
export const processSubmission = webMethod(Permissions.Anyone, (submitRequestData) => {
return wixCaptcha.authorize(submitRequestData.token)
.then(() => {
return wixData.insert("MailingList", submitRequestData.data);
});
});
```
### See also
* [$w.captcha API](https://dev.wix.com/docs/velo/api-reference/$w/captcha/introduction.md)
* [wix-captcha-backend API](https://dev.wix.com/docs/velo/api-reference/wix-captcha-backend/introduction.md)