Skip to content

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:

typescript
{
  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 ​

typescript
{
  type: 'text';
  name: string;
  label: string;
  default?: string;
  placeholder?: string;
  maxLength?: number;
  pattern?: string; // Regex pattern
}

Example ​

typescript
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 ​

typescript
{
  type: 'number';
  name: string;
  label: string;
  default?: number;
  min?: number;
  max?: number;
  step?: number;
}

Example ​

typescript
{
  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 ​

typescript
{
  type: 'richtext';
  name: string;
  label: string;
  default?: string; // HTML string
}

Usage in Component ​

typescript
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 ​

typescript
{
  type: 'image';
  name: string;
  label: string;
  default?: string; // URL
}

Usage in Component ​

typescript
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 ​

typescript
{
  type: 'color';
  name: string;
  label: string;
  default?: string; // Hex color
  presets?: string[]; // Preset color options
}

Example ​

typescript
{
  type: 'color',
  name: 'backgroundColor',
  label: 'Background Color',
  default: '#ffffff',
  presets: ['#ffffff', '#f3f4f6', '#1f2937', '#3b82f6']
}

Select Option ​

Dropdown selection from predefined options.

Type Definition ​

typescript
{
  type: 'select';
  name: string;
  label: string;
  options: Array<{ label: string; value: string }>;
  default?: string;
}

Example ​

typescript
{
  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 ​

typescript
{
  type: 'checkbox';
  name: string;
  label: string;
  default?: boolean;
}

Example ​

typescript
{
  type: 'checkbox',
  name: 'showButton',
  label: 'Show Call-to-Action Button',
  default: true
}

Component Option ​

Nested component slot for composition.

Type Definition ​

typescript
{
  type: 'component';
  name: string;
  label: string;
  allowedComponents?: string[]; // Restrict to specific components
}

Usage in Component ​

typescript
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 ​

typescript
{
  type: 'entity';
  name: string;
  label: string;
  collectionName: string; // Which collection to query
  default?: string; // Entity ID
}

Example ​

typescript
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 ​

typescript
{
  type: 'entity-multiple';
  name: string;
  label: string;
  collectionName: string;
  default?: string[]; // Array of entity IDs
  max?: number; // Maximum selections
}

Example ​

typescript
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 ​

typescript
{
  type: 'page';
  name: string;
  label: string;
  default?: string; // Page ID or slug
}

Example ​

typescript
{
  type: 'page',
  name: 'linkedPage',
  label: 'Link to Page',
  default: '/'
}

Page Multiple Option ​

Links to multiple pages in the site.

Type Definition ​

typescript
{
  type: 'page-multiple';
  name: string;
  label: string;
  default?: string[]; // Array of page IDs/slugs
  max?: number;
}

Example ​

typescript
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 ​

typescript
{
  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 ​

typescript
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 ​

typescript
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:

typescript
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:

typescript
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:

typescript
{
  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:

typescript
{
  type: 'text',
  name: 'title',
  label: 'Title',
  default: 'Welcome' // ✅ Good
}

{
  type: 'text',
  name: 'title',
  label: 'Title'
  // ❌ Bad - No default
}

2. Use Clear Labels ​

typescript
// ✅ Good
{
  label: "Call-to-Action Button Text";
}

// ❌ Bad
{
  label: "CTA Btn Txt";
}

3. Add Help Text ​

typescript
{
  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:

typescript
// ✅ 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:

typescript
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 ​

Reference ​

See the complete TypeScript types in @blocksweb/core/types.