---
title: "Validate form data"
section: "build-ui/formbuilder"
platforms: ["javascript", "react", "nextjs"]
gen: 2
last-updated: "2024-10-29T23:36:56.000Z"
url: "https://docs.amplify.aws/react/build-ui/formbuilder/validations/"
---

Sanitize user input by adding validation rules to your form. By default, Amplify generated forms infers a range of validation rules based on the data model. For example, given a data model with an `AWSEmail` field, the generated form input will automatically run an email validation rule.

## Configurable validation rules

By default, the following validation rules are available for you to configure:

| Input type | Configurable validation rule |
| --- | --- |
| `String` | - Start With <br/> - End With <br/> - Contain <br/> - Does not contain <br/> - Be less than N characters long <br/> - Be at least N characters long <br/> |
| `Int`, `Float` | - Be greater than <br/> - Be less than <br/> - Be equal to <br/> |
| `AWSDate`, `AWSTime`, `AWSDateTime` | - Be before <br/> - Be after <br/> |

### Automatically configured validation rules

For the types below, we automatically apply validation rules on form inputs:

- `AWSIPAddress`: input value must be a valid IPv4 or IPv6 address.
- `AWSURL`: input value must consist of a schema (`http`, `mailto`) and a path part. Path part can't contain two forward slashes (//).
- `AWSEmail`: input value must be an email address in the format `<local-part>@<domain-part>`.
- `AWSJSON`: input value must be a valid JSON.
- `AWSPhone`: input value must be a phone number that can contain either spaces or hyphens to separate digit groups.

## Add validation rules

Every form provides an `onValidate` event handler to provide additional validation rules via code. Return an object with validation functions for the fields you want to validate. In the example below, `address` must start with a number, otherwise return any existing auto-generated validation responses.

```jsx
<HomeCreateForm
  onValidate={{
    address: (value, validationResponse) => {
      const firstWord = value.split('')[0];
      if (!isNaN(firstWord)) {
        // check if the first word is a number
        return {
          hasError: true,
          errorMessage: 'Address must start with a number'
        };
      }
      return validationResponse;
    }
  }}
/>
```

**Note:** the validation function must return a validation response of the following shape:

```ts
type ValidationResponse = {
  hasError: boolean;
  errorMessage?: string;
};
```

### Add validation rules for nested JSON data

Amplify generated forms can also produce nested JSON object. For example, you can create a new `ProductForm` component based on the following JSON object:

```json
{
  "name": "Piano",
  "price": {
    "maxDiscount": 0.15,
    "default": 999,
    "currency": "$"
  }
}
```

To add validation rules to the nested objects, pass in validation functions in the same nested structure as the data:

```js
<ProductForm
  onValidate={{
    price: {
      currency: (value, validationResponse) => {
        // Pass validation function to match the nested object
        const allowedCurrencies = ['$', '€', '￥', '₹'];
        if (!allowedCurrencies.includes(value)) {
          return {
            hasError: true,
            errorMessage: 'Currency must be either "$", "€", "￥", or "₹".'
          };
        }
        return validationResponse;
      }
    }
  }}
  onSubmit={(fields) => {
    /* handle form data submission */
  }}
/>
```

### Call external APIs for asynchronous form validation

Sometimes your form needs to asynchronously validate an input with an external API or database before the form data is submitted.

Return a Promise in the `onValidate` prop to run an asynchronous validation rule. In the following example, we check with an external API if a real estate agent exist based on a given license number:

```jsx
<AgentContactForm
  onValidate={{
    licenseNumber: (value, validationResponse) => {
      // fetch calls an external API,
      // which ultimately returns a Promise<ValidationResponse>
      return fetch(`http://localhost:3000/api/agent/${value}`).then(
        (response) => {
          if (response.status !== 200) {
            return {
              // If the request failed, return a validation error
              hasError: true,
              errorMessage: 'No agent was not found with that license number.'
            };
          }
          return validationResponse;
        }
      );
    }
  }}
  onSubmit={(fields) => {
    /* Handle form submission */
  }}
/>
```
