Schema Validation
This document covers JSON Schema validation keywords that can be used in the Extra Schema Definitions field when setting up properties in a schema.
Overview
Total CMS uses JSON Schema (Draft 2020-12) for data validation. In addition to the basic schema properties (type, field, label, etc.), you can add validation constraints to ensure data quality and consistency.
Where to add these: In the Schema admin interface, when editing a property, use the Extra Schema Definitions field to add validation keywords as JSON.
Required Fields
By default, required string and array fields are automatically validated:
- Strings: Cannot be empty (
"") - Arrays (list, gallery, deck): Cannot be empty (
[]) - Files/Images: Validated on the frontend (must have a file uploaded)
You can override this behavior by explicitly setting minLength or minItems.
String Validation
minLength / maxLength
Enforce minimum and maximum string length.
{
"minLength": 3,
"maxLength": 100
}
Example - Username field:
{
"username": {
"type": "string",
"field": "text",
"label": "Username",
"minLength": 3,
"maxLength": 20
}
}
Use cases:
- Usernames (3-20 characters)
- Product names (minimum 5 characters)
- Short descriptions (maximum 200 characters)
- Passwords (minimum 8 characters)
pattern
Validate strings against a regular expression.
{
"pattern": "^[a-zA-Z0-9_-]+$"
}
Example - Slug field:
{
"slug": {
"type": "string",
"field": "text",
"label": "URL Slug",
"pattern": "^[a-z0-9-]+$"
}
}
Common patterns:
- Alphanumeric:
^[a-zA-Z0-9]+$ - URL-safe slug:
^[a-z0-9-]+$ - Hex color:
^#[0-9A-Fa-f]{6}$ - Phone (US):
^\\d{3}-\\d{3}-\\d{4}$
format
Use built-in format validators.
{
"format": "email"
}
Available formats:
email- Email addressuri/url- URLdate- Date (YYYY-MM-DD)time- Time (HH:MM:SS)date-time- ISO 8601 date-timeipv4/ipv6- IP address
Example:
{
"website": {
"type": "string",
"field": "url",
"label": "Website",
"format": "uri"
}
}
Number Validation
minimum / maximum
Enforce minimum and maximum numeric values.
{
"minimum": 0,
"maximum": 100
}
Example - Percentage field:
{
"discount": {
"type": "number",
"field": "number",
"label": "Discount %",
"minimum": 0,
"maximum": 100
}
}
exclusiveMinimum / exclusiveMaximum
Like minimum/maximum, but excludes the boundary value.
{
"exclusiveMinimum": 0,
"exclusiveMaximum": 100
}
Example - Temperature (must be above 0, not equal to 0):
{
"temperature": {
"type": "number",
"field": "number",
"label": "Temperature (°C)",
"exclusiveMinimum": 0
}
}
multipleOf
Ensure number is a multiple of a specified value.
{
"multipleOf": 5
}
Example - Quantity (in packs of 5):
{
"quantity": {
"type": "integer",
"field": "number",
"label": "Quantity",
"multipleOf": 5,
"minimum": 5
}
}
Array Validation
minItems / maxItems
Enforce minimum and maximum array length.
{
"minItems": 1,
"maxItems": 10
}
Example - Tags field:
{
"tags": {
"$ref": "https://www.totalcms.co/schemas/properties/list.json",
"label": "Tags",
"minItems": 1,
"maxItems": 5
}
}
Use cases:
- Tags (1-5 items)
- Gallery (minimum 3 images)
- Options (maximum 10 choices)
- Team members (minimum 2 members)
uniqueItems
Ensure all items in an array are unique.
{
"uniqueItems": true
}
Example - Category tags:
{
"categories": {
"$ref": "https://www.totalcms.co/schemas/properties/list.json",
"label": "Categories",
"uniqueItems": true
}
}
Note: The list property type already has uniqueItems: true by default.
Enum (Allowed Values)
Restrict values to a specific set of allowed options.
{
"enum": ["draft", "published", "archived"]
}
Example - Status field:
{
"status": {
"type": "string",
"field": "select",
"label": "Status",
"enum": ["draft", "published", "archived"],
"options": [
{"value": "draft", "label": "Draft"},
{"value": "published", "label": "Published"},
{"value": "archived", "label": "Archived"}
]
}
}
Use cases:
- Predefined statuses
- Size options (S, M, L, XL)
- Priority levels (low, medium, high)
- Content types
Combining Validations
You can combine multiple validation keywords for comprehensive data validation.
Example - Product SKU:
{
"sku": {
"type": "string",
"field": "text",
"label": "Product SKU",
"minLength": 8,
"maxLength": 12,
"pattern": "^[A-Z]{3}-[0-9]{4,8}$"
}
}
Example - Price field:
{
"price": {
"type": "number",
"field": "number",
"label": "Price (USD)",
"minimum": 0.01,
"maximum": 999999.99,
"multipleOf": 0.01
}
}
Example - Feature list:
{
"features": {
"$ref": "https://www.totalcms.co/schemas/properties/list.json",
"label": "Product Features",
"minItems": 3,
"maxItems": 10,
"uniqueItems": true
}
}
Unique Values
unique
Ensure that a property's value is unique across all objects in the collection.
{
"unique": true
}
Example - Email field:
{
"email": {
"$ref": "https://www.totalcms.co/schemas/properties/email.json",
"label": "Email Address",
"unique": true
}
}
Example - Username field:
{
"username": {
"type": "string",
"field": "text",
"label": "Username",
"unique": true,
"minLength": 3,
"maxLength": 20
}
}
Important requirements:
- Must be indexed: Unique properties must be included in the schema's
indexarray for performance - Case-sensitive: Uniqueness validation is case-sensitive (e.g., "test@example.com" and "TEST@example.com" are considered different)
- Empty values allowed: Multiple objects can have empty/null values for a unique field
- Update behavior: When updating an object, you can keep the same value, but cannot change to a value used by another object
Use cases:
- User emails (prevent duplicate registrations)
- Usernames (ensure unique login identifiers)
- Product SKUs (avoid inventory conflicts)
- Slug fields (ensure unique URLs)
Error message: When a duplicate value is detected, users will see an error message like:
Email must be unique. The value 'john@example.com' already exists in another object.
Schema setup example with index:
{
"id": "user",
"type": "object",
"properties": {
"id": {
"type": "string",
"label": "ID",
"field": "input"
},
"email": {
"$ref": "https://www.totalcms.co/schemas/properties/email.json",
"label": "Email",
"unique": true
},
"username": {
"type": "string",
"label": "Username",
"field": "text",
"unique": true
}
},
"required": ["id", "email", "username"],
"index": ["id", "email", "username"]
}
Note: If you mark a property as unique but don't include it in the index, you'll receive a helpful error message prompting you to add it to the index.
Disabling Automatic Required Validation
If you want to allow empty values for a required field, explicitly set:
Allow empty strings (for required fields):
{
"minLength": 0
}
Allow empty arrays (for required fields):
{
"minItems": 0
}
Example - Optional notes on a required field:
{
"notes": {
"type": "string",
"field": "textarea",
"label": "Additional Notes",
"minLength": 0,
"maxLength": 500
}
}
Error Messages
When validation fails, Total CMS will display clear error messages to users:
- minLength/maxLength: "String must be at least X characters" or "String exceeds maximum length of X"
- minimum/maximum: "Value must be at least X" or "Value must not exceed X"
- pattern: "Value does not match required format"
- enum: "Value must be one of: X, Y, Z"
- minItems/maxItems: "Array must contain at least X items" or "Array exceeds maximum of X items"
Best Practices
- Be specific: Use validation to enforce your data requirements clearly
- Provide context: Use
helptext to explain validation requirements to users - Balance strictness: Don't over-validate - allow reasonable flexibility
- Test thoroughly: Verify validation works as expected in the admin interface
- Consider UX: Validation should help users, not frustrate them
Common Validation Patterns
Email with length limits
{
"email": {
"$ref": "https://www.totalcms.co/schemas/properties/email.json",
"label": "Email Address",
"maxLength": 255
}
}
Phone number (US format)
{
"phone": {
"$ref": "https://www.totalcms.co/schemas/properties/phone.json",
"label": "Phone Number",
"pattern": "^\\d{3}-\\d{3}-\\d{4}$"
}
}
Postal code (US ZIP)
{
"zipcode": {
"type": "string",
"field": "text",
"label": "ZIP Code",
"pattern": "^\\d{5}(-\\d{4})?$"
}
}
Percentage (0-100)
{
"completion": {
"type": "integer",
"field": "range",
"label": "Completion %",
"minimum": 0,
"maximum": 100
}
}
Required gallery (minimum 3 images)
{
"gallery": {
"$ref": "https://www.totalcms.co/schemas/properties/gallery.json",
"label": "Product Images",
"minItems": 3,
"maxItems": 20
}
}
Unique username with validation
{
"username": {
"type": "string",
"field": "text",
"label": "Username",
"unique": true,
"minLength": 3,
"maxLength": 20,
"pattern": "^[a-z0-9_-]+$"
}
}
Unique email address
{
"email": {
"$ref": "https://www.totalcms.co/schemas/properties/email.json",
"label": "Email Address",
"unique": true,
"maxLength": 255
}
}
Reference
For complete JSON Schema documentation, see: