Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Laravel HTML
https://github.com/spatie/laravel-html
Admin
Laravel HTML is a package that provides a clean and simple API for generating HTML elements
...
Tokens:
14,797
Snippets:
115
Trust Score:
8.5
Update:
3 months ago
Context
Skills
Chat
Benchmark
88.9
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Laravel HTML Builder ## Introduction Laravel HTML is a fluent HTML builder package for Laravel applications that provides a clean, chainable API for generating HTML elements dynamically. The package focuses on making HTML and form generation painless by offering an expressive syntax that eliminates the need for manual string concatenation and reduces errors in HTML markup. It integrates seamlessly with Laravel's ecosystem, automatically handling CSRF tokens, HTTP method spoofing, old input values from failed form submissions, and model attribute binding. The library follows immutability principles where each method call returns a new instance, making it safe to reuse element definitions throughout your application. All HTML elements are generated through a central `Html` builder class, which can be accessed via the `html()` helper function or the `Html` facade. Elements support extensive customization through fluent method chaining for attributes, classes, styles, data attributes, and nested children, making it ideal for both simple and complex HTML generation scenarios. ## API Reference and Code Examples ### Creating Basic HTML Elements Generate standard HTML elements with optional content and attributes. ```php use Spatie\Html\Facades\Html; // Create a link echo html()->a('https://example.com', 'Visit Site'); // <a href="https://example.com">Visit Site</a> // Create a div with content echo html()->div('Hello World')->class('container'); // <div class="container">Hello World</div> // Create a span with attributes echo html()->span('Badge')->class('badge badge-primary')->id('user-badge'); // <span class="badge badge-primary" id="user-badge">Badge</span> // Create a paragraph echo html()->p('This is a paragraph')->style('color: red'); // <p style="color: red">This is a paragraph</p> // Create a button echo html()->button('Click Me', 'button')->class('btn btn-primary')->disabled(); // <button type="button" class="btn btn-primary" disabled="disabled">Click Me</button> // Create a mailto link echo html()->mailto('hello@example.com', 'Contact Us'); // <a href="mailto:hello@example.com">Contact Us</a> // Create a tel link echo html()->tel('+1234567890', 'Call Us'); // <a href="tel:+1234567890">Call Us</a> // Create a custom element echo html()->element('article')->class('post')->html('<h2>Title</h2>'); // <article class="post"><h2>Title</h2></article> ``` ### Building Forms with Automatic CSRF Protection Create forms with automatic CSRF token injection and HTTP method spoofing. ```php // Basic POST form echo html()->form('POST', '/users')->open(); echo html()->text('username')->placeholder('Enter username'); echo html()->submit('Create User'); echo html()->form()->close(); // Output: // <form method="POST" action="/users"> // <input type="hidden" name="_token" value="abc123"> // <input type="text" name="username" id="username" placeholder="Enter username"> // <button type="submit">Create User</button> // </form> // Form with method spoofing for PUT/PATCH/DELETE echo html()->form('PUT', '/users/1')->open(); echo html()->email('email')->required(); echo html()->submit('Update'); echo html()->form()->close(); // Output: // <form method="POST" action="/users/1"> // <input type="hidden" name="_method" value="PUT"> // <input type="hidden" name="_token" value="abc123"> // <input type="email" name="email" id="email" required="required"> // <button type="submit">Update</button> // </form> // GET form (no CSRF token) echo html()->form('GET', '/search')->open(); echo html()->search('query')->placeholder('Search...'); echo html()->submit('Search'); echo html()->form()->close(); // Output: // <form method="GET" action="/search"> // <input type="search" name="query" id="query" placeholder="Search..."> // <button type="submit">Search</button> // </form> // Form with route helper echo html()->form('POST')->route('user.store')->open(); // Uses Laravel's route() helper to resolve the URL // Form with file upload support echo html()->form('POST', '/upload')->acceptsFiles()->open(); echo html()->file('avatar')->required(); echo html()->submit('Upload'); echo html()->form()->close(); // Adds enctype="multipart/form-data" to the form ``` ### Model-Bound Forms with Auto-Population Bind forms to Eloquent models for automatic field population from model attributes. ```php // Create a model-bound form $user = User::find(1); // User with name="John Doe", email="john@example.com" echo html()->modelForm($user, 'PUT', '/users/1')->open(); echo html()->text('name'); echo html()->email('email'); echo html()->select('status', ['active' => 'Active', 'inactive' => 'Inactive']); echo html()->closeModelForm(); // Output: // <form method="POST" action="/users/1"> // <input type="hidden" name="_method" value="PUT"> // <input type="hidden" name="_token" value="abc123"> // <input type="text" name="name" id="name" value="John Doe"> // <input type="email" name="email" id="email" value="john@example.com"> // <select name="status" id="status"> // <option value="active" selected="selected">Active</option> // <option value="inactive">Inactive</option> // </select> // </form> // Manual model binding html()->model($user); echo html()->text('name'); // Automatically uses $user->name echo html()->password('password'); // Passwords never auto-populate html()->endModel(); // Nested attributes with array notation $profile = ['user' => ['address' => ['city' => 'New York']]]; html()->model($profile); echo html()->text('user[address][city]'); // <input type="text" name="user[address][city]" id="user[address][city]" value="New York"> // Enum support (PHP 8.1+) enum Status: int { case Pending = 1; case Complete = 2; } $task = Task::find(1); // Task with status = Status::Pending html()->model($task); echo html()->select('status', [ Status::Pending->value => 'Pending', Status::Complete->value => 'Complete' ]); // Automatically selects the option matching Status::Pending->value ``` ### Input Fields with Various Types Generate input fields with automatic old value population and validation attributes. ```php // Text input with attributes echo html()->text('username', 'default_value') ->placeholder('Enter username') ->class('form-control') ->required() ->autofocus() ->maxlength(50); // <input type="text" name="username" id="username" value="default_value" // placeholder="Enter username" class="form-control" required="required" // autofocus="autofocus" maxlength="50"> // Email input echo html()->email('email')->required()->autocomplete('email'); // <input type="email" name="email" id="email" required="required" autocomplete="email"> // Password input (never shows old values) echo html()->password('password')->required()->minlength(8); // <input type="password" name="password" id="password" required="required" minlength="8"> // Hidden input echo html()->hidden('user_id', 42); // <input type="hidden" name="user_id" id="user_id" value="42"> // Number input with constraints echo html()->number('quantity', 1, 1, 100, 1) ->placeholder('Quantity') ->required(); // <input type="number" name="quantity" id="quantity" value="1" // min="1" max="100" step="1" placeholder="Quantity" required="required"> // Range slider echo html()->range('volume', 50, 0, 100, 5); // <input type="range" name="volume" id="volume" value="50" min="0" max="100" step="5"> // Date input with automatic formatting $date = '2024-01-15 10:30:00'; echo html()->date('birthday', $date); // <input type="date" name="birthday" id="birthday" value="2024-01-15"> // DateTime input echo html()->datetime('appointment', '2024-01-15 10:30:00'); // <input type="datetime-local" name="appointment" id="appointment" value="2024-01-15T10:30:00"> // Time input echo html()->time('opening_time', '09:00:00'); // <input type="time" name="opening_time" id="opening_time" value="09:00:00"> // File upload echo html()->file('avatar')->accept('image/*'); // <input type="file" name="avatar" id="avatar" accept="image/*"> // Search input echo html()->search('q')->placeholder('Search...'); // <input type="search" name="q" id="q" placeholder="Search..."> ``` ### Checkboxes and Radio Buttons Create checkbox and radio inputs with automatic checked state handling. ```php // Basic checkbox echo html()->checkbox('agree', false, '1'); // <input type="checkbox" name="agree" id="agree" value="1"> // Checked checkbox echo html()->checkbox('subscribe', true, 'yes'); // <input type="checkbox" name="subscribe" id="subscribe" checked="checked" value="yes"> // Checkbox with custom value echo html()->checkbox('terms', false, 'accepted')->required(); // <input type="checkbox" name="terms" id="terms" value="accepted" required="required"> // Radio button echo html()->radio('gender', false, 'male'); echo html()->radio('gender', false, 'female'); // <input type="radio" name="gender" id="gender_male" value="male"> // <input type="radio" name="gender" id="gender_female" value="female"> // Radio with one selected echo html()->radio('status', true, 'active'); echo html()->radio('status', false, 'inactive'); // <input type="radio" name="status" id="status_active" value="active" checked="checked"> // <input type="radio" name="status" id="status_inactive" value="inactive"> // Radio buttons with labels $options = ['small' => 'Small', 'medium' => 'Medium', 'large' => 'Large']; foreach ($options as $value => $label) { echo html()->label([ html()->radio('size', $value === 'medium', $value), ' ' . $label ]); } ``` ### Select Dropdowns with Options Generate select elements with simple arrays, nested optgroups, and automatic selection. ```php // Basic select with options $options = [ 'us' => 'United States', 'ca' => 'Canada', 'mx' => 'Mexico' ]; echo html()->select('country', $options, 'us'); // <select name="country" id="country"> // <option value="us" selected="selected">United States</option> // <option value="ca">Canada</option> // <option value="mx">Mexico</option> // </select> // Select with placeholder echo html()->select('city', $options)->placeholder('Select a city'); // Adds an empty option at the beginning // Required select echo html()->select('category', $options)->required(); // <select name="category" id="category" required="required">...</select> // Multiselect echo html()->multiselect('tags[]', [ 'php' => 'PHP', 'laravel' => 'Laravel', 'javascript' => 'JavaScript' ], ['php', 'laravel']); // <select name="tags[]" id="tags[]" multiple="multiple"> // <option value="php" selected="selected">PHP</option> // <option value="laravel" selected="selected">Laravel</option> // <option value="javascript">JavaScript</option> // </select> // Select with optgroups $groupedOptions = [ 'Fruits' => [ 'apple' => 'Apple', 'banana' => 'Banana' ], 'Vegetables' => [ 'carrot' => 'Carrot', 'lettuce' => 'Lettuce' ] ]; echo html()->select('food', $groupedOptions, 'apple'); // <select name="food" id="food"> // <optgroup label="Fruits"> // <option value="apple" selected="selected">Apple</option> // <option value="banana">Banana</option> // </optgroup> // <optgroup label="Vegetables"> // <option value="carrot">Carrot</option> // <option value="lettuce">Lettuce</option> // </optgroup> // </select> // Select with Laravel Collection $users = User::all()->pluck('name', 'id'); echo html()->select('user_id', $users); ``` ### Textarea with Content Create textarea elements with automatic value population and constraints. ```php // Basic textarea echo html()->textarea('description', 'Default text'); // <textarea name="description" id="description">Default text</textarea> // Textarea with attributes echo html()->textarea('bio') ->placeholder('Tell us about yourself') ->rows(5) ->class('form-control') ->required() ->maxlength(500); // <textarea name="bio" id="bio" placeholder="Tell us about yourself" // rows="5" class="form-control" required="required" maxlength="500"></textarea> // Read-only textarea echo html()->textarea('terms', 'Terms and conditions...') ->readonly(); // <textarea name="terms" id="terms" readonly="readonly">Terms and conditions...</textarea> ``` ### Labels, Fieldsets, and Form Structure Organize form elements with semantic HTML structure. ```php // Label with for attribute echo html()->label('Email Address', 'email')->class('form-label'); // <label for="email" class="form-label">Email Address</label> // Label wrapping an input echo html()->label([ html()->checkbox('remember', false, '1'), ' Remember me' ]); // <label> // <input type="checkbox" name="remember" id="remember" value="1"> // Remember me // </label> // Fieldset with legend echo html()->fieldset('Personal Information') ->addChild(html()->label('Name', 'name')) ->addChild(html()->text('name')) ->addChild(html()->label('Email', 'email')) ->addChild(html()->email('email')); // <fieldset> // <legend>Personal Information</legend> // <label for="name">Name</label> // <input type="text" name="name" id="name"> // <label for="email">Email</label> // <input type="email" name="email" id="email"> // </fieldset> // Submit and reset buttons echo html()->submit('Save Changes')->class('btn btn-primary'); // <button type="submit" class="btn btn-primary">Save Changes</button> echo html()->reset('Clear Form')->class('btn btn-secondary'); // <button type="reset" class="btn btn-secondary">Clear Form</button> ``` ### Element Attributes and Chaining Manipulate element attributes using fluent method chaining and conditional methods. ```php // Setting multiple attributes $input = html()->text('username') ->class('form-control') ->id('user-input') ->attribute('data-validate', 'required') ->data('max-length', '50') ->aria('label', 'Username input'); // <input type="text" name="username" class="form-control" id="user-input" // data-validate="required" data-max-length="50" aria-label="Username input"> // Conditional attributes $isRequired = true; echo html()->email('contact') ->requiredIf($isRequired) ->classIf($isRequired, 'required-field'); // <input type="email" name="contact" id="contact" required="required" class="required-field"> // Unless conditions $isDisabled = false; echo html()->button('Submit') ->disabledUnless(!$isDisabled) ->classUnless($isDisabled, 'btn-active'); // Conditional with null check $placeholder = 'Enter email'; echo html()->email('email')->placeholderIfNotNull($placeholder); // Style attribute echo html()->div('Content') ->style(['color' => 'red', 'font-size' => '14px']); // <div style="color: red; font-size: 14px">Content</div> echo html()->span('Text')->style('font-weight: bold'); // <span style="font-weight: bold">Text</span> // Adding multiple classes echo html()->div()->class('container')->class('mx-auto')->class('p-4'); // <div class="container mx-auto p-4"></div> // Removing attributes $element = html()->text('name')->required(); $element = $element->forgetAttribute('required'); // <input type="text" name="name" id="name"> ``` ### Building Nested Elements Create complex HTML structures with nested children elements. ```php // Adding children to elements echo html()->div() ->class('card') ->addChild(html()->div('Header')->class('card-header')) ->addChild(html()->div('Body content')->class('card-body')) ->addChild(html()->div('Footer')->class('card-footer')); // <div class="card"> // <div class="card-header">Header</div> // <div class="card-body">Body content</div> // <div class="card-footer">Footer</div> // </div> // Using children() method with array echo html()->div([ html()->span('Item 1'), html()->span('Item 2'), html()->span('Item 3') ])->class('items'); // <div class="items"> // <span>Item 1</span> // <span>Item 2</span> // <span>Item 3</span> // </div> // Prepending children echo html()->div() ->addChild(html()->p('Second')) ->prependChild(html()->p('First')); // <div> // <p>First</p> // <p>Second</p> // </div> // Complex nested structure echo html()->form('POST', '/submit')->open(); echo html()->div([ html()->fieldset('User Details')->addChild([ html()->label('Name', 'name'), html()->text('name')->required(), html()->label('Email', 'email'), html()->email('email')->required() ]), html()->div([ html()->submit('Save')->class('btn-primary'), html()->reset('Cancel')->class('btn-secondary') ])->class('form-actions') ])->class('form-container'); echo html()->form()->close(); // Conditional children $showExtra = true; echo html()->div() ->addChild(html()->p('Always visible')) ->addChildIf($showExtra, html()->p('Conditionally visible')); ``` ### Element Immutability and Reusability Leverage immutable element instances for safe reuse across your application. ```php // Elements are immutable - each method returns a new instance $baseButton = html()->button('Click')->class('btn'); $primaryButton = $baseButton->class('btn-primary'); $secondaryButton = $baseButton->class('btn-secondary'); echo $primaryButton; // <button type="button" class="btn btn-primary">Click</button> echo $secondaryButton; // <button type="button" class="btn btn-secondary">Click</button> echo $baseButton; // <button type="button" class="btn">Click</button> // Reusable form field templates $formControl = fn($type, $name) => html()->input($type, $name) ->class('form-control') ->required(); echo $formControl('text', 'username'); echo $formControl('email', 'email'); // Icon pattern $icon = html()->i()->class('fa'); echo $icon->class('fa-home'); // <i class="fa fa-home"></i> echo $icon->class('fa-user'); // <i class="fa fa-user"></i> echo $icon->class('fa-search'); // <i class="fa fa-search"></i> ``` ### Opening and Closing Tags Generate separate opening and closing tags for template flexibility. ```php // Using open() and close() methods echo html()->div()->class('container')->open(); echo '<p>Content goes here</p>'; echo '<p>More content</p>'; echo html()->div()->close(); // Output: // <div class="container"> // <p>Content goes here</p> // <p>More content</p> // </div> // Form with open/close echo html()->form('POST', '/submit')->class('user-form')->open(); // ... blade template content ... echo html()->form()->close(); // Fieldset pattern echo html()->fieldset()->open(); echo html()->legend('Section Title'); // ... form fields ... echo html()->fieldset()->close(); ``` ### Extending the HTML Builder Extend functionality using Laravel's Macroable trait for custom element methods. ```php use Spatie\Html\Facades\Html; use Spatie\Html\Elements\Input; // Register a macro on the Html builder Html::macro('bootstrap5Input', function ($name, $label, $value = null) { return html()->div([ html()->label($label, $name)->class('form-label'), html()->text($name, $value)->class('form-control'), ])->class('mb-3'); }); // Use the macro echo html()->bootstrap5Input('username', 'Username', 'john_doe'); // <div class="mb-3"> // <label for="username" class="form-label">Username</label> // <input type="text" name="username" id="username" value="john_doe" class="form-control"> // </div> // Register element-level macro Input::macro('bootstrap', function () { return $this->class('form-control')->attribute('data-bs-theme', 'dark'); }); echo html()->text('email')->bootstrap(); // <input type="text" name="email" id="email" class="form-control" data-bs-theme="dark"> // Custom element shortcut Html::macro('alertBox', function ($message, $type = 'info') { return html()->div($message) ->class("alert alert-{$type}") ->attribute('role', 'alert'); }); echo html()->alertBox('Operation successful!', 'success'); // <div class="alert alert-success" role="alert">Operation successful!</div> ``` ### Working with Old Input Values Automatic integration with Laravel's session flash data for form repopulation. ```php // When validation fails, Laravel redirects with old input // The HTML builder automatically uses these values // In your controller after validation fails: // return redirect()->back()->withInput(); // Your view will automatically repopulate: echo html()->text('username'); // Uses old('username') automatically echo html()->email('email'); // Uses old('email') automatically // Manual old value retrieval $value = html()->value('field_name', 'default'); // Equivalent to: old('field_name', 'default') // Old values work with model binding // Priority: old() > model attribute > default value $user = User::find(1); html()->model($user); echo html()->text('name'); // If old('name') exists, uses that, otherwise uses $user->name // Array field names are converted echo html()->text('user[profile][city]'); // Internally converts to old('user.profile.city') ``` ## Summary and Integration Patterns Laravel HTML Builder streamlines HTML generation in Laravel applications by providing a type-safe, fluent API that reduces template complexity and eliminates common errors. The primary use cases include building dynamic forms with automatic CSRF protection, creating reusable UI components through element immutability, and implementing model-backed forms that auto-populate from Eloquent models or session data. The package excels at handling form validation workflows where old input values need to be preserved after failed submissions, making it particularly valuable for CRUD operations and multi-step forms. Additional use cases include generating navigation menus, creating data tables with dynamic columns, building email templates, and constructing admin interfaces where form fields need consistent styling and behavior. The package integrates seamlessly with Laravel's ecosystem through automatic service provider registration, facade support, and a global `html()` helper function. Common integration patterns include using macros to define project-specific form components, combining with Blade components for encapsulating complex UI patterns, and leveraging the immutability pattern to create base element templates that can be safely reused across controllers and views. The builder works naturally with Laravel Collections, request validation, route helpers, and Eloquent model binding, making it a cohesive addition to any Laravel project. For team consistency, it's recommended to define standard form field macros in a service provider and use the builder throughout your Blade templates instead of raw HTML to maintain a single source of truth for element generation.