export const metadata = { title: "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
```json
{
"type": "TextField",
"props": {
"label": "Email",
"valuePath": "/form/email",
"checks": [
{ "fn": "required", "message": "Email is required" },
{ "fn": "email", "message": "Invalid email format" }
],
"validateOn": "blur"
}
}
```
## Validation with Parameters
```json
{
"type": "TextField",
"props": {
"label": "Password",
"valuePath": "/form/password",
"checks": [
{ "fn": "required", "message": "Password is required" },
{
"fn": "minLength",
"args": { "length": 8 },
"message": "Password must be at least 8 characters"
},
{
"fn": "pattern",
"args": { "pattern": "[A-Z]" },
"message": "Must contain at least one uppercase letter"
}
]
}
}
```
## Custom Validation Functions
Define custom validators in your catalog:
```typescript
import { defineCatalog } from '@json-render/core';
import { schema } from '@json-render/react';
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',
},
},
});
```
Then implement them in your ValidationProvider:
```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}
))}