LaraBuilder Visual Editor
Complete guide to using LaraBuilder, LaraDashboard's drag-and-drop visual page builder for creating pages and email templates.
LaraBuilder Visual Editor
LaraBuilder is LaraDashboard's powerful drag-and-drop visual editor for creating pages, posts, and email templates without writing code. This guide covers everything from basic usage to creating custom blocks.
Overview
What is LaraBuilder?
LaraBuilder is a React-based visual content builder that provides:
- Drag-and-Drop Interface - Intuitive block placement
- Real-time Preview - See changes instantly
- Responsive Design - Preview across device sizes
- Undo/Redo - Full history support
- Custom Blocks - Extensible block system
Use Cases
| Context | Description |
|---|---|
| Pages | Landing pages, about pages, contact |
| Posts | Rich blog posts with complex layouts |
| Email Templates | HTML emails with visual design |
| Campaigns | Marketing content with CTAs |
Getting Started
Accessing the Builder
- Create or edit a post/page
- Click "Use Visual Builder"
- The builder interface loads
Builder Interface
┌─────────────────────────────────────────────────────────────────────────┐
│ [Save] [Preview] [Settings] [Undo] [Redo] [Desktop/Mobile] │
├─────────────────┬───────────────────────────────────────────────────────┤
│ │ │
│ BLOCKS │ CANVAS │
│ │ │
│ ┌───────────┐ │ ┌─────────────────────────────────────────────┐ │
│ │ Layout │ │ │ │ │
│ ├───────────┤ │ │ [Drop blocks here] │ │
│ │ Text │ │ │ │ │
│ ├───────────┤ │ └─────────────────────────────────────────────┘ │
│ │ Media │ │ │
│ ├───────────┤ │ ┌─────────────────────────────────────────────┐ │
│ │ Buttons │ │ │ Section Block │ │
│ ├───────────┤ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ Forms │ │ │ │ Column │ │ Column │ │ Column │ │ │
│ ├───────────┤ │ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ Advanced │ │ └─────────────────────────────────────────────┘ │
│ └───────────┘ │ │
│ │ │
├─────────────────┴───────────────────────────────────────────────────────┤
│ SETTINGS PANEL (appears when block selected) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Content │ Style │ Advanced │ │
│ │ ───────────────────────────────────────────────────────────── │ │
│ │ Text: [_______________] │ │
│ │ Alignment: [Left] [Center] [Right] │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
Working with Blocks
Adding Blocks
- Drag from Library - Drag block from sidebar to canvas
- Click to Add - Click block to append to canvas
- Copy/Paste - Duplicate existing blocks
Block Categories
Layout Blocks
| Block | Description |
|---|---|
| Section | Container for other blocks |
| Columns | Multi-column layout (2, 3, 4 cols) |
| Container | Centered width container |
| Spacer | Vertical spacing |
| Divider | Horizontal separator |
Text Blocks
| Block | Description |
|---|---|
| Heading | H1-H6 headers |
| Paragraph | Rich text content |
| Rich Text | Full WYSIWYG editor |
| Quote | Blockquote styling |
| List | Ordered/unordered lists |
Media Blocks
| Block | Description |
|---|---|
| Image | Single image with options |
| Gallery | Image grid/carousel |
| Video | YouTube, Vimeo, self-hosted |
| Icon | Icon library selection |
| Logo | Site logo with link |
Interactive Blocks
| Block | Description |
|---|---|
| Button | CTA buttons with styles |
| Link | Text links |
| Accordion | Collapsible content |
| Tabs | Tabbed content panels |
| Modal | Popup content |
Form Blocks
| Block | Description |
|---|---|
| Form | Contact/subscribe form |
| Input | Text input field |
| Textarea | Multi-line input |
| Select | Dropdown selection |
| Checkbox | Boolean input |
Advanced Blocks
| Block | Description |
|---|---|
| HTML | Custom HTML code |
| Code | Syntax highlighted code |
| Embed | External embeds |
| Shortcode | Dynamic shortcodes |
Configuring Blocks
Click any block to open its settings panel:
Content Tab
Edit the block's content:
- Text content
- Images/media
- Links and URLs
- Dynamic variables
Style Tab
Customize appearance:
- Colors (text, background, border)
- Typography (font, size, weight)
- Spacing (margin, padding)
- Borders (width, radius, style)
- Shadows and effects
Advanced Tab
Advanced options:
- CSS classes
- Custom ID
- HTML attributes
- Visibility conditions
- Animation effects
Block Operations
| Action | Method |
|---|---|
| Select | Click on block |
| Move | Drag to reposition |
| Duplicate | Click duplicate icon or Ctrl+D |
| Delete | Click trash icon or Delete key |
| Copy | Ctrl+C |
| Paste | Ctrl+V |
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Ctrl/Cmd + S |
Save |
Ctrl/Cmd + Z |
Undo |
Ctrl/Cmd + Shift + Z |
Redo |
Ctrl/Cmd + D |
Duplicate block |
Delete |
Delete selected block |
Escape |
Deselect block |
↑ ↓ |
Navigate between blocks |
Responsive Design
Preview Modes
Toggle between device views:
- Desktop (1200px+)
- Tablet (768px - 1199px)
- Mobile (< 768px)
Responsive Settings
Many style options have per-breakpoint controls:
Padding:
Desktop: 40px
Tablet: 30px
Mobile: 20px
Visibility Control
Show/hide blocks per device:
- Show on desktop only
- Hide on mobile
- Custom visibility rules
Dynamic Content
Variables
Insert dynamic content using variables:
{{site_name}}
{{user.name}}
{{post.title}}
{{current_year}}
Conditional Content
Show content based on conditions:
@if($user->isPremium())
Premium content here
@else
Regular content
@endif
Saving & Publishing
Save Options
| Option | Description |
|---|---|
| Save Draft | Save without publishing |
| Publish | Save and make live |
| Schedule | Set future publish date |
Design Storage
Builder designs are stored as JSON:
{
"blocks": [
{
"type": "section",
"id": "abc123",
"settings": {...},
"children": [...]
}
],
"settings": {
"theme": "default"
}
}
HTML Output
Pages and posts are rendered from the saved JSON (design_json) each time they're shown, so dynamic blocks such as Latest Posts stay current. The content HTML column is kept as a snapshot and used only when a post has no design JSON.
Video Embeds
The Video block embeds a responsive player on pages for YouTube (including youtu.be and Shorts links), Vimeo and Dailymotion URLs. Direct video files (.mp4, .webm, …) use the browser's native player. In emails, where players can't run, the block shows the video thumbnail linked to the video.
Content Sanitizing (v1.4.9+)
Builder content is sanitized when it's saved and again whenever it's loaded, for every block type — including module blocks and blocks created with make:block. Script tags, on* event handlers, Alpine and Livewire directives (x-*, @*, wire:*) and javascript: links are removed, so content from one editor can't run code in the builder, the admin post view, email previews or the public page. https:// iframes are kept.
The Code block keeps its escaped source, so code samples still display. Block renderers also escape colors, sizes, gaps and custom CSS before they reach style attributes. If you write a custom block, escape every prop you output in its renderer (e() in PHP) — sanitizing is a safety net, not a replacement.
Email Template Building
Email Context
When building email templates:
- Limited block selection (email-safe)
- Inline CSS output
- Table-based layouts
- Preview in email clients
Email-Safe Blocks
- Header/Footer
- Text blocks
- Images
- Buttons (table-based)
- Columns (table-based)
- Dividers
- Spacers
Testing Emails
- Click Preview
- Select Send Test Email
- Enter recipient
- Check in email client
Creating Custom Blocks
Block Structure
// app/Services/Builder/Blocks/CustomBlock.php
namespace App\Services\Builder\Blocks;
use App\Services\Builder\Block;
class CustomBlock extends Block
{
public string $type = 'custom-block';
public string $title = 'Custom Block';
public string $icon = 'custom-icon';
public string $category = 'advanced';
public function getDefaultSettings(): array
{
return [
'title' => 'Default Title',
'content' => '',
'style' => 'default',
];
}
public function getSettingsSchema(): array
{
return [
[
'name' => 'title',
'label' => 'Title',
'type' => 'text',
'tab' => 'content',
],
[
'name' => 'content',
'label' => 'Content',
'type' => 'richtext',
'tab' => 'content',
],
[
'name' => 'style',
'label' => 'Style',
'type' => 'select',
'options' => [
'default' => 'Default',
'highlighted' => 'Highlighted',
'minimal' => 'Minimal',
],
'tab' => 'style',
],
];
}
public function render(array $settings): string
{
return view('blocks.custom-block', $settings)->render();
}
}
Registering Blocks
// In service provider
use App\Services\Builder\BlockRegistryService;
public function boot()
{
$registry = app(BlockRegistryService::class);
$registry->register(new CustomBlock());
}
Block View Template
{{-- resources/views/blocks/custom-block.blade.php --}}
<div class="custom-block custom-block--{{ $style }}">
<h3 class="custom-block__title">{{ $title }}</h3>
<div class="custom-block__content">
{!! $content !!}
</div>
</div>
Block React Component
For advanced interactivity, create a React component:
// resources/js/lara-builder/blocks/CustomBlock.jsx
import React from 'react';
import { useBlock } from '../hooks/useBlock';
export default function CustomBlock({ block }) {
const { settings, updateSettings } = useBlock(block);
return (
<div className={`custom-block custom-block--${settings.style}`}>
<input
value={settings.title}
onChange={(e) => updateSettings({ title: e.target.value })}
className="block-title-input"
/>
<RichTextEditor
value={settings.content}
onChange={(content) => updateSettings({ content })}
/>
</div>
);
}
Hooks & Filters
Builder Hooks
use TorMorten\Eventy\Facades\Events as Eventy;
// Register custom blocks
Eventy::action('builder.register_blocks', function ($registry) {
$registry->register(new MyCustomBlock());
});
// Filter available blocks
$blocks = Eventy::filter('builder.blocks', $blocks, $context);
// Before save
Eventy::action('builder.saving', function ($design, $post) {
// Validate or transform
});
// After render
$html = Eventy::filter('builder.rendered_html', $html, $design);
Troubleshooting
Builder Not Loading
- Clear browser cache
- Check JavaScript console for errors
- Verify assets are built:
npm run build - Check for conflicting plugins
Blocks Not Rendering
- Verify block is registered
- Check view template exists
- Review render method for errors
- Check permissions
Styles Not Applying
- Check CSS specificity
- Verify Tailwind is configured
- Rebuild assets
- Clear view cache
Undo Not Working
- Check browser memory
- Reduce design complexity
- Save more frequently
Best Practices
Design
- Start with a section block
- Use columns for layout
- Add spacers for breathing room
- Maintain visual hierarchy
- Test on all devices
Performance
- Optimize images before upload
- Limit number of blocks
- Use lazy loading for media
- Minimize custom CSS
Accessibility
- Use proper heading hierarchy
- Add alt text to images
- Ensure sufficient color contrast
- Test with screen readers
Next Steps
- Content Management - Use builder for content
- Email Templates - Build email designs
- Module Development - Create custom blocks