> ## Documentation Index
> Fetch the complete documentation index at: https://docs.overflow.co/llms.txt
> Use this file to discover all available pages before exploring further.

# required

> Reject empty inputs at submit time. Cascades to atoms on multi-field elements.

`required` marks an element (or an individual atom on a multi-field element) as mandatory. Empty inputs surface a `FieldError` with `code: 'required'`.

Defaults to `false`. When `false`, an empty input is treated as a valid "not provided" value: `onChange` emits `value: null` with no errors and `submit()` accepts the empty submission.

## Single-input elements

`email`, `fullName`, `phone`, and `companyName` accept a top-level `required?: boolean`.

```javascript theme={null}
overflow.email({ required: true });
overflow.phone({ required: true });
```

When `true`, the element emits a `FieldError` with `code: 'required'` whenever its input is empty: at submit time, on blur, and from `onChange` as soon as the value becomes empty again. Backspacing to empty re-emits the required error immediately.

### Split-mode `fullName`

`required: true` cascades to both halves. Each empty half emits its own `FieldError` with `field: 'firstName'` or `field: 'lastName'`.

## Address elements

`billingAddress` and `shippingAddress` accept either a boolean or a per-atom record:

```typescript theme={null}
type MultiFieldRequired<TFieldKey extends string> =
  | boolean
  | Partial<Record<TFieldKey, boolean>>;

type AddressFieldKey =
  | 'line1' | 'line2' | 'city' | 'state' | 'zip' | 'country';
```

| Shape                                         | Behavior                                                                                                                   |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| unset                                         | The element is fully optional. Empty atoms emit no `required` errors.                                                      |
| `required: true`                              | Cascades to `line1`, `city`, `state`, `zip`, and `country`. `line2` stays optional by convention.                          |
| `required: { line1: true, line2: true, ... }` | Per-atom override. Atoms not listed (or set to `false`) are optional. Hidden atoms are excluded from the cascade entirely. |

```javascript theme={null}
overflow.billingAddress({
  required: { line1: true, city: true, state: true, zip: true, country: true, line2: false },
});
```

The optional `fields.fullName` slot on an address element owns its own `required` knob (configured inside `fields.fullName.required`). It is not addressable through the address-level record.

## Bank element

`bank` does not expose a top-level `required` knob. Both modes are implicitly required:

* Address-lookup mode: the shopper must complete linking before submit succeeds. An unlinked submit surfaces a single `FieldError` with `field: 'bank'` and `code: 'required'` and the message `"Please link your bank to continue."`.
* Manual mode: every visible atom (`accountType`, `routingNumber`, `accountNumber`, `confirmAccountNumber`) is implicitly required and collects a `required` `FieldError` when empty. `accountType` only trips the required-empty branch when `fields.accountType.placeholder` is configured.

## Card element

`card` does not accept `required` at any level. Every card field is always required. Suppress optional fields with `fields.holderName.hidden` or `fields.postalCode.hidden` instead.

## Custom elements

`text`, `number`, and `select` accept a top-level `required?: boolean`. An empty input (or the placeholder slot on `select`) emits a `FieldError` with `code: 'required'`.

`checkbox` interprets `required: true` as "must be checked", matching the native HTML `<input type="checkbox" required>` semantic.

## Container elements

`checkout`, `submitButton`, `applePay`, and `googlePay` do not accept `required`. Configure per-slot required on the contact and address slots inside `checkout` instead.

## Error shape

```typescript theme={null}
{
  field: 'email',       // element's field key
  code: 'required',
  message: 'Email is required',  // interpolated from label
}
```

Read errors from `onChange.errors` (live) or `onError.fieldErrors` (submit time). Both surfaces share the same `FieldError` shape.

## See also

* [`validate`](/payment-elements/options/validate)
* [`onError` and `fieldErrors`](/payment-elements/events/on-error)
* [Handle validation errors](/payment-elements/guides/handle-validation-errors)
