Skip to content

Components & Schema

Learn how BlocksWeb components work and how to define schemas that make them editable.

What is a BlocksWeb Component?

A BlocksWeb component is a React component with an attached schema that describes its editable properties.

typescript
import { IBlockswebComponent } from '@blocksweb/core';

const Hero: IBlockswebComponent = ({ title, subtitle }) => {
  return (
    <section>
      <h1>{title}</h1>
      <p>{subtitle}</p>
    </section>
  );
};

Hero.schema = {
  displayName: 'Hero Section',
  options: [
    { type: 'text', name: 'title', label: 'Title', default: 'Welcome' },
    { type: 'text', name: 'subtitle', label: 'Subtitle', default: 'Get started' },
  ]
};

export default Hero;

Component Anatomy

1. Component Function

The React component that renders your UI:

typescript
const Hero: IBlockswebComponent = (props) => {
  // Your component logic
  return <div>...</div>;
};

2. Schema Object

Defines how the component appears and behaves in the editor:

typescript
Hero.schema = {
  displayName: 'Hero Section',  // Name in component picker
  category: 'Marketing',        // Category grouping (optional)
  description: 'Hero banner',   // Description (optional)
  icon: 'hero-icon',            // Icon name (optional)
  options: []                   // Editable properties
};

3. Options Array

Each option creates an editable property:

typescript
options: [
  {
    type: 'text',              // Input type
    name: 'title',             // Prop name
    label: 'Hero Title',       // Label in editor
    default: 'Welcome',        // Default value
    help: 'Main page heading', // Help text (optional)
  }
]

Schema Properties

displayName (required)

typescript
displayName: 'Hero Section'

How the component appears in the component picker.

category (optional)

typescript
category: 'Marketing' // or 'Content', 'Layout', 'E-commerce', etc.

Groups related components together in the picker.

description (optional)

typescript
description: 'Large hero banner with title and call-to-action'

Shows additional information about the component.

icon (optional)

typescript
icon: 'hero' // Icon identifier

Custom icon for the component in the picker.

options (required)

typescript
options: [
  { type: 'text', name: 'title', label: 'Title', default: 'Welcome' },
  // More options...
]

Array of editable properties. See Options Reference for all types.

TypeScript Types

Use TypeScript for type-safe components:

typescript
import { IBlockswebComponent } from '@blocksweb/core';

type HeroProps = {
  title: string;
  subtitle: string;
  buttonText?: string;
  buttonUrl?: string;
};

const Hero: IBlockswebComponent<HeroProps> = ({
  title,
  subtitle,
  buttonText,
  buttonUrl
}) => {
  return (
    <section>
      <h1>{title}</h1>
      <p>{subtitle}</p>
      {buttonText && buttonUrl && (
        <a href={buttonUrl}>{buttonText}</a>
      )}
    </section>
  );
};

Hero.schema = {
  displayName: 'Hero Section',
  options: [
    { type: 'text', name: 'title', label: 'Title', default: '' },
    { type: 'text', name: 'subtitle', label: 'Subtitle', default: '' },
    { type: 'text', name: 'buttonText', label: 'Button Text', default: '' },
    { type: 'text', name: 'buttonUrl', label: 'Button URL', default: '' },
  ]
};

Best Practices

1. Provide Good Defaults

Always set default values so components look good immediately:

typescript
options: [
  {
    type: 'text',
    name: 'title',
    label: 'Title',
    default: 'Welcome to Our Website' // Good default
  }
]

2. Use Clear Names

Choose descriptive displayNames and labels:

typescript
// Good
displayName: 'Hero Banner with CTA'
label: 'Call to Action Button Text'

// Avoid
displayName: 'Hero'
label: 'CTA'

Use categories to organize components:

typescript
// Marketing components
Hero.schema = { category: 'Marketing', ... };
CallToAction.schema = { category: 'Marketing', ... };

// Content components
RichText.schema = { category: 'Content', ... };
ImageGallery.schema = { category: 'Content', ... };

4. Add Help Text

Guide users with helpful descriptions:

typescript
{
  type: 'text',
  name: 'metaDescription',
  label: 'Meta Description',
  help: 'Keep between 150-160 characters for best SEO',
  default: ''
}

Next Steps