Options Reference
Options are the heart of BlocksWeb - they define what properties your components expose to the visual editor. This comprehensive guide covers all 12 option types and their configurations.
Overview
Every option has these common properties:
{
type: string; // The option type
name: string; // The prop name in your component
label: string; // Display name in the editor
default?: any; // Default value
required?: boolean; // Whether the field is required
help?: string; // Help text shown to users
}Text Option
Simple single-line text input.
Type Definition
{
type: 'text';
name: string;
label: string;
default?: string;
placeholder?: string;
maxLength?: number;
pattern?: string; // Regex pattern
}Example
Hero.schema = {
displayName: 'Hero',
options: [
{
type: 'text',
name: 'title',
label: 'Page Title',
default: 'Welcome to Our Website',
placeholder: 'Enter title...',
maxLength: 60,
help: 'Keep it under 60 characters for best SEO'
}
]
};Number Option
Numeric input with optional min/max constraints.
Type Definition
{
type: 'number';
name: string;
label: string;
default?: number;
min?: number;
max?: number;
step?: number;
}Example
{
type: 'number',
name: 'columns',
label: 'Number of Columns',
default: 3,
min: 1,
max: 6,
step: 1
}Rich Text Option
Full rich text editor with formatting, links, lists, and more.
Type Definition
{
type: 'richtext';
name: string;
label: string;
default?: string; // HTML string
}Usage in Component
import { RichText } from '@blocksweb/core/client';
const MyComponent: IBlockswebComponent = ({ content }) => {
return (
<div>
<RichText
propName="content"
text={content}
defaultText="<p>Default content</p>"
/>
</div>
);
};
MyComponent.schema = {
displayName: 'Content Block',
options: [
{
type: 'richtext',
name: 'content',
label: 'Content',
default: '<p>Enter your content here</p>'
}
]
};Image Option
Image picker with asset manager integration.
Type Definition
{
type: 'image';
name: string;
label: string;
default?: string; // URL
}Usage in Component
import { Image } from '@blocksweb/core/client';
const MyComponent: IBlockswebComponent = ({ heroImage }) => {
return (
<Image
propName="heroImage"
asset={heroImage}
default="/placeholder.jpg"
alt="Hero image"
/>
);
};
MyComponent.schema = {
displayName: 'Image Block',
options: [
{
type: 'image',
name: 'heroImage',
label: 'Hero Image',
default: '/default-hero.jpg'
}
]
};Color Option
Color picker with hex, RGB, and preset support.
Type Definition
{
type: 'color';
name: string;
label: string;
default?: string; // Hex color
presets?: string[]; // Preset color options
}Example
{
type: 'color',
name: 'backgroundColor',
label: 'Background Color',
default: '#ffffff',
presets: ['#ffffff', '#f3f4f6', '#1f2937', '#3b82f6']
}Select Option
Dropdown selection from predefined options.
Type Definition
{
type: 'select';
name: string;
label: string;
options: Array<{ label: string; value: string }>;
default?: string;
}Example
{
type: 'select',
name: 'alignment',
label: 'Text Alignment',
options: [
{ label: 'Left', value: 'left' },
{ label: 'Center', value: 'center' },
{ label: 'Right', value: 'right' }
],
default: 'center'
}Checkbox Option
Boolean toggle switch.
Type Definition
{
type: 'checkbox';
name: string;
label: string;
default?: boolean;
}Example
{
type: 'checkbox',
name: 'showButton',
label: 'Show Call-to-Action Button',
default: true
}Component Option
Nested component slot for composition.
Type Definition
{
type: 'component';
name: string;
label: string;
allowedComponents?: string[]; // Restrict to specific components
}Usage in Component
import { BlockOutlet } from '@blocksweb/core/client';
const Container: IBlockswebComponent = ({ children }) => {
return (
<div className="container">
<BlockOutlet propName="children" blocks={children} />
</div>
);
};
Container.schema = {
displayName: 'Container',
options: [
{
type: 'component',
name: 'children',
label: 'Content',
allowedComponents: ['Hero', 'FeatureCard', 'RichContent']
}
]
};Entity Option
Reference to a single entity from a collection.
Type Definition
{
type: 'entity';
name: string;
label: string;
collectionName: string; // Which collection to query
default?: string; // Entity ID
}Example
import { useCollectionRecord } from '@blocksweb/core/client';
const ProductShowcase: IBlockswebComponent = ({ productId }) => {
const { data: product } = useCollectionRecord('products', productId);
if (!product) return <div>Loading...</div>;
return (
<div>
<h2>{product.name}</h2>
<p>{product.price}</p>
</div>
);
};
ProductShowcase.schema = {
displayName: 'Product Showcase',
options: [
{
type: 'entity',
name: 'productId',
label: 'Select Product',
collectionName: 'products'
}
]
};Entity Multiple Option
References to multiple entities from a collection.
Type Definition
{
type: 'entity-multiple';
name: string;
label: string;
collectionName: string;
default?: string[]; // Array of entity IDs
max?: number; // Maximum selections
}Example
import { useCollectionRecords } from '@blocksweb/core/client';
const ProductGrid: IBlockswebComponent = ({ productIds }) => {
const { data: products } = useCollectionRecords('products', productIds);
return (
<div className="grid grid-cols-3 gap-4">
{products?.map(product => (
<div key={product.id}>
<h3>{product.name}</h3>
<p>${product.price}</p>
</div>
))}
</div>
);
};
ProductGrid.schema = {
displayName: 'Product Grid',
options: [
{
type: 'entity-multiple',
name: 'productIds',
label: 'Select Products',
collectionName: 'products',
max: 6
}
]
};Page Option
Link to a single page in the site.
Type Definition
{
type: 'page';
name: string;
label: string;
default?: string; // Page ID or slug
}Example
{
type: 'page',
name: 'linkedPage',
label: 'Link to Page',
default: '/'
}Page Multiple Option
Links to multiple pages in the site.
Type Definition
{
type: 'page-multiple';
name: string;
label: string;
default?: string[]; // Array of page IDs/slugs
max?: number;
}Example
const Navigation: IBlockswebComponent = ({ pages }) => {
return (
<nav>
{pages.map(page => (
<a key={page.id} href={page.slug}>
{page.name}
</a>
))}
</nav>
);
};
Navigation.schema = {
displayName: 'Navigation',
options: [
{
type: 'page-multiple',
name: 'pages',
label: 'Navigation Pages',
max: 10
}
]
};Collection Option
Reference to developer-defined collection records. BlocksWeb automatically resolves the IDs to full objects.
How It Works
When a user selects collection records in the editor, BlocksWeb stores the record IDs. When your component renders, BlocksWeb automatically fetches and resolves those IDs to full record objects. You receive complete data, not IDs!
Type Definition
{
type: 'collection';
name: string;
label: string;
collectionName: string; // Which collection to use
multiple?: boolean; // Single or multiple selection (default: false)
default?: string | string[] | null;
}Single Selection Example
const BlogPostCard: IBlockswebComponent = ({ selectedPost }) => {
// selectedPost is the FULL OBJECT, not an ID!
// BlocksWeb automatically resolved it for you
if (!selectedPost) {
return <div>No post selected</div>;
}
return (
<article>
<h2>{selectedPost.title}</h2>
<p>By {selectedPost.author}</p>
<div>{selectedPost.content}</div>
</article>
);
};
BlogPostCard.schema = {
displayName: 'Blog Post Card',
options: [
{
type: 'collection',
name: 'selectedPost', // Receives full object, not ID
label: 'Select Blog Post',
collectionName: 'blogPosts',
multiple: false, // Single selection
default: null
}
]
};Multiple Selection Example
const ProductGrid: IBlockswebComponent = ({ selectedProducts = [] }) => {
// selectedProducts is array of FULL OBJECTS, not IDs!
// BlocksWeb automatically resolved them for you
return (
<div className="grid grid-cols-3 gap-4">
{selectedProducts.map(product => (
<div key={product.id}>
<img src={product.image} alt={product.name} />
<h3>{product.name}</h3>
<p>${product.price}</p>
<span>{product.inStock ? 'In Stock' : 'Out of Stock'}</span>
</div>
))}
</div>
);
};
ProductGrid.schema = {
displayName: 'Product Grid',
options: [
{
type: 'collection',
name: 'selectedProducts', // Receives array of full objects
label: 'Select Products',
collectionName: 'products',
multiple: true, // Multiple selection
default: []
}
]
};Behind the Scenes
1. Editor UI: User selects records
→ IDs stored: ["1", "2", "3"]
2. Page renders (server or client)
→ BlocksWeb automatically fetches records
3. Your component receives:
→ Full objects: [{ id: "1", name: "...", ... }, ...]
No hooks needed! Just use the data.Advanced Patterns
Conditional Options
Show/hide options based on other values:
options: [
{
type: 'checkbox',
name: 'showImage',
label: 'Show Image',
default: true
},
{
type: 'image',
name: 'image',
label: 'Image',
// Only show if showImage is true
condition: { field: 'showImage', value: true }
}
]Option Groups
Group related options together:
options: [
{
group: 'Content',
items: [
{ type: 'text', name: 'title', label: 'Title' },
{ type: 'richtext', name: 'description', label: 'Description' }
]
},
{
group: 'Styling',
items: [
{ type: 'color', name: 'bgColor', label: 'Background' },
{ type: 'select', name: 'alignment', label: 'Alignment' }
]
}
]Dynamic Default Values
Use functions for dynamic defaults:
{
type: 'text',
name: 'id',
label: 'Component ID',
default: () => `component-${Date.now()}`
}Best Practices
1. Provide Sensible Defaults
Always set defaults so components look good immediately:
{
type: 'text',
name: 'title',
label: 'Title',
default: 'Welcome' // ✅ Good
}
{
type: 'text',
name: 'title',
label: 'Title'
// ❌ Bad - No default
}2. Use Clear Labels
// ✅ Good
{ label: 'Call-to-Action Button Text' }
// ❌ Bad
{ label: 'CTA Btn Txt' }3. Add Help Text
{
type: 'text',
name: 'metaDescription',
label: 'Meta Description',
help: 'Keep between 150-160 characters for best SEO results',
maxLength: 160
}4. Limit Choices
Don't overwhelm users with too many options:
// ✅ Good - 3-5 options
{
type: 'select',
name: 'size',
options: [
{ label: 'Small', value: 'sm' },
{ label: 'Medium', value: 'md' },
{ label: 'Large', value: 'lg' }
]
}
// ❌ Bad - Too many options
{
type: 'select',
name: 'fontSize',
options: Array.from({ length: 50 }, (_, i) => ({
label: `${i + 10}px`,
value: `${i + 10}px`
}))
}5. Use TypeScript
Type your props to match your options:
type MyComponentProps = {
title: string; // type: 'text'
count: number; // type: 'number'
visible: boolean; // type: 'checkbox'
bgColor: string; // type: 'color'
alignment: 'left' | 'center' | 'right'; // type: 'select'
};Next Steps
- Creating Components - Build components with options
- Utilities - Use RichText, Image, BlockOutlet
- Collections - Work with structured data
Reference
See the complete TypeScript types in @blocksweb/core/types.