import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("docs/validation")
# Validation
Validate form inputs with built-in and custom functions.
## Built-in Validators
json-render includes common validation functions:
- `required` — Value must be non-empty
- `email` — Valid email format
- `minLength` — Minimum string length
- `maxLength` — Maximum string length
- `pattern` — Match a regex pattern
- `min` — Minimum numeric value
- `max` — Maximum numeric value
## Using Validation in JSON
Use `{ "$bindState": "/path" }` on the value prop for two-way binding. Validation checks run against the value at the bound path (available as `bindings?.value` in components):
```json
{
"type": "TextField",
"props": {
"label": "Email",
"value": { "$bindState": "/form/email" },
"checks": [
{ "type": "required", "message": "Email is required" },
{ "type": "email", "message": "Invalid email format" }
],
"validateOn": "blur"
}
}
```
## Validation with Parameters
```json
{
"type": "TextField",
"props": {
"label": "Password",
"value": { "$bindState": "/form/password" },
"checks": [
{ "type": "required", "message": "Password is required" },
{
"type": "minLength",
"args": { "min": 8 },
"message": "Password must be at least 8 characters"
},
{
"type": "pattern",
"args": { "pattern": "[A-Z]" },
"message": "Must contain at least one uppercase letter"
}
]
}
}
```
## Custom Validation Functions
Define custom validators in your catalog's `functions` field. The catalog itself is framework-agnostic — only the `schema` import varies by platform:
```typescript
import { defineCatalog } from '@json-render/core';
import { schema } from '@json-render/react/schema'; // or '@json-render/react-native/schema'
import { z } from 'zod';
const catalog = defineCatalog(schema, {
components: { /* ... */ },
functions: {
isValidPhone: {
description: 'Validates phone number format',
},
isUniqueEmail: {
description: 'Checks if email is not already registered',
},
},
});
```
## Usage with React
In `@json-render/react`, use `ValidationProvider` to supply implementations for your custom validators:
```tsx
import { ValidationProvider } from '@json-render/react';
function App() {
const customValidators = {
isValidPhone: (value) => {
const phoneRegex = /^\+?[1-9]\d{1,14}$/;
return phoneRegex.test(value);
},
isUniqueEmail: async (value) => {
const response = await fetch(`/api/check-email?email=${value}`);
const { available } = await response.json();
return available;
},
};
return (
{error}
))}