Skip to content

Aurora 1.0 is out!

What's new →
Docs menu

Building a site

Creating blocks

A PHP class and a Blade view: what a block is and how to make one.

A block is one PHP class and one Blade view. The same view renders on the website, on the editor's canvas and in previews.

~ Terminal
$ php artisan aurora:make-block "Pricing table" --category=marketing --icon=phosphor-currency-circle-dollar
$ php artisan aurora:make-block "Two columns" --container      # a block that holds other blocks

This creates app/Blocks/PricingTableBlock.php and resources/views/components/blocks/pricing-table.blade.php. Blocks in app/Blocks are registered automatically. The class says what the block is:

app/Blocks/CardBlock.php PHP
namespace App\Blocks;

use Aurora\Blocks\Block;
use Aurora\Blocks\Editable;
use Aurora\Blocks\Fields;
use Aurora\Filament\Forms\Components\AssetPicker;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;

class CardBlock extends Block
{
    public static function type(): string { return 'card'; }               // stored in the page JSON
    public static function label(): string { return __('Card'); }
    public static function description(): string { return __('Image, title, text and a link in a box.'); }
    public static function icon(): ?string { return 'phosphor-identification-card'; }
    public static function category(): string { return 'content'; }         // palette group

    // The inspector's fields: any Filament form components.
    public static function schema(): array
    {
        return [
            AssetPicker::make('image')->label(__('Image')),                     // a media library image
            TextInput::make('title')->label(__('Title')),
            Textarea::make('body')->label(__('Text'))->rows(3),
            ...Fields::link(),                                                  // page, file or URL
        ];
    }

    // What a new block starts with.
    public static function defaults(): array
    {
        return ['title' => 'Card title', 'body' => 'Why this matters.'];
    }

    // Fields editors type into right on the canvas.
    public static function editables(): array
    {
        return [
            'title' => Editable::text()->placeholder(__('Title')),
            'body' => Editable::text()->multiline(),
        ];
    }

    // Told to AI assistants: when to use it, and how.
    public static function aiHints(): ?string
    {
        return 'Normally placed inside a "grid". The card becomes clickable when it has a link.';
    }
}

More a block can say

MethodWhat it does
itemEditables()Inline editing inside repeater items, such as FAQ questions
sameInEveryLanguage()Fields that aren't translated (links, numbers, settings)
preview()A picture of the block for the palette (or upload one in Settings › Blocks)
isVisible()Hide a block from some people, like code blocks

Container blocks

Blocks that hold other blocks implement Aurora\Blocks\Contracts\Container, declare their slots, and draw each one with block_slot():

PHP
use Aurora\Blocks\Contracts\Container;

class BandBlock extends Block implements Container
{
    public static function slots(array $data): array { return ['content']; }
    // …
}
Blade
<section class="band">{{ block_slot('content') }}</section>

Ordering and registering by hand

Blocks from other folders, or in a set palette order, are registered from a service provider: Blocks::register([HeroBlock::class, CardBlock::class]). A type registered again replaces the earlier one, so a site can override a library block.

What you get for free

  • validated when AI tools write it;
  • described to AI assistants by list_block_types, built from the schema;
  • translated block by block, and indexed for search;
  • served structured by the REST and GraphQL APIs: images, page links and forms come out as what they point at.

This website's blocks

This website is built from 24 blocks of its own, in its app/Blocks. They're good examples to read or start from.

CategoryBlocks
LayoutSection band, Responsive grid, Button group
ContentHeading, Paragraph, Rich text, Button, Card, Callout, Accordion / FAQ, Tabs, Steps / timeline
MarketingHero, Feature, Statistic, Pricing plan, Testimonial, Team member, Logo cloud, Call to action
MediaImage, Gallery
DynamicForm, Page list
DeveloperCode sample

The page builder adds Section (columns), List, Quote, Spacer, Divider, Video, Embed, Shortcode and Code.