Block Examples & Patterns
Real-world JSON examples showing the power of nested blocks.
Basic Examples
Simple Contact Form
A single-page contact form with validation:
{
"id": "contact-form",
"type": "form",
"metadata": { "formName": "Contact Us" },
"initialPage": "contact",
"pages": {
"contact": {
"id": "contact",
"blockType": "PageBlock",
"blocks": [
{
"id": "page-content",
"blockType": "PageContentBlock",
"blocks": [
{
"id": "contact-card",
"blockType": "CardBlock",
"blocks": [
{
"id": "name",
"blockType": "InputBlock",
"metadata": {
"label": "Name",
"contextPath": "contact.name"
},
"validations": [
{
"rule": "charMinLength",
"value": 2,
"message": "Name must be at least 2 characters"
}
]
},
{
"id": "email",
"blockType": "InputBlock",
"metadata": {
"label": "Email",
"contextPath": "contact.email"
}
},
{
"id": "submit",
"blockType": "ButtonBlock",
"metadata": { "label": "Submit" },
"actions": [
{
"type": "callApi",
"service": "submitContact"
}
]
}
]
}
]
}
]
}
}
}Multi-Step Form with Sidebar
A multi-page form with sidebar navigation:
{
"id": "onboarding",
"type": "form",
"initialPage": "step1",
"blocks": [
{
"id": "sidebar",
"blockType": "SidebarBlock",
"blocks": [
{
"id": "sidebar-items",
"blockType": "SidebarItemsBlock",
"blocks": [
{
"id": "step1-nav",
"blockType": "SidebarItemBlock",
"metadata": {
"label": "Personal Info",
"page": "step1"
}
},
{
"id": "step2-nav",
"blockType": "SidebarItemBlock",
"metadata": {
"label": "Address",
"page": "step2"
}
}
]
}
]
}
],
"pages": {
"step1": {
"id": "step1",
"blockType": "PageBlock",
"blocks": [
{
"id": "header",
"blockType": "PageHeaderBlock",
"blocks": [
{
"id": "title",
"blockType": "HeaderBlock",
"metadata": {
"heading": "h1",
"text": "Personal Information"
}
}
]
},
{
"id": "content",
"blockType": "PageContentBlock",
"blocks": [
{
"id": "name-row",
"blockType": "RowBlock",
"blocks": [
{
"id": "first-name",
"blockType": "InputBlock",
"metadata": {
"label": "First Name",
"contextPath": "user.firstName"
}
},
{
"id": "last-name",
"blockType": "InputBlock",
"metadata": {
"label": "Last Name",
"contextPath": "user.lastName"
}
}
]
}
]
},
{
"id": "footer",
"blockType": "PageFooterBlock",
"blocks": [
{
"id": "next",
"blockType": "ButtonBlock",
"metadata": { "label": "Next" },
"actions": [
{
"type": "goToPage",
"target": "step2"
}
]
}
]
}
]
}
}
}Advanced Patterns
Conditional Fields
Show/hide fields based on user selection:
{
"id": "entity-type",
"blockType": "SelectBlock",
"metadata": {
"label": "Entity Type",
"contextPath": "entityType",
"options": [
{ "label": "Individual", "value": "individual" },
{ "label": "Business", "value": "business" }
]
}
},
{
"id": "business-name",
"blockType": "InputBlock",
"metadata": {
"label": "Business Name",
"contextPath": "businessName"
},
"displayConditions": [
{
"matchType": "exact",
"field": "entityType",
"value": "business"
}
]
}Validation with Actions
Check email availability on change:
{
"id": "email",
"blockType": "InputBlock",
"metadata": {
"label": "Email",
"contextPath": "user.email"
},
"validations": [
{
"rule": "pattern",
"value": "/^[^@]+@[^@]+\\.[^@]+$/",
"message": "Please enter a valid email"
}
],
"actions": [
{
"trigger": "onChange",
"type": "conditional",
"conditions": [
{
"matchType": "isValid",
"field": "email"
}
],
"then": [
{
"type": "callApi",
"service": "checkEmailAvailability"
}
]
}
]
}Nested Cards Layout
Create a pricing comparison with nested blocks:
{
"id": "pricing-row",
"blockType": "RowBlock",
"blocks": [
{
"id": "basic-card",
"blockType": "CardBlock",
"metadata": { "text": "Basic Plan" },
"blocks": [
{
"id": "basic-price",
"blockType": "ParagraphBlock",
"metadata": { "text": "$9/month" }
},
{
"id": "basic-features",
"blockType": "CardBlock",
"blocks": [
{
"id": "feature-1",
"blockType": "ParagraphBlock",
"metadata": { "text": "✓ 10 forms" }
},
{
"id": "feature-2",
"blockType": "ParagraphBlock",
"metadata": { "text": "✓ 100 responses" }
}
]
},
{
"id": "select-basic",
"blockType": "ButtonBlock",
"metadata": { "label": "Choose Basic" },
"actions": [
{
"type": "assignContext",
"assign": {
"selectedPlan": "basic"
}
},
{
"type": "goToPage",
"target": "checkout"
}
]
}
]
},
{
"id": "premium-card",
"blockType": "CardBlock",
"metadata": { "text": "Premium Plan" },
"blocks": [
// Similar structure...
]
}
]
}Tips & Best Practices
Organizing Complex Forms
- Use meaningful IDs:
step1-personal-firstNamevsfield1 - Group related fields: Use
CardBlockorRowBlock - Break into pages: Multi-step for better UX
- Add navigation: SidebarBlock for progress tracking
Performance
- Lazy load pages: Only render current page
- Debounce API calls: Built-in 500ms debounce
- Minimize nesting: 3-4 levels is usually enough
- Use displayConditions: Don't render hidden blocks
Maintainability
- Separate JSON files: One per form or page
- Use JSON schema: Validate your config
- Document metadata: Comment expected fields
- Version control: Track JSON changes
🚀 See It In Action
Check out our live interactive examples to see these patterns in real forms!