Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

hiviyan's avatar

Package laravelcollective/html is abandoned, you should avoid using it. Use spatie/laravel-html instead

Now, I just found out this message while running "composer update", which basically says that we should start using "spatie/laravel-html" instead. Is this really true? Can we still use laravelcollective/html?

Package laravelcollective/html is abandoned, you should avoid using it. Use spatie/laravel-html instead

I am still new to "spatie/laravel-html". Can this new package do whatever FormFacade and HtmlFacade could do in laravelcollective/html?

0 likes
20 replies
LaryAI's avatar
Level 58

Yes, it is true that the package laravelcollective/html is abandoned and it is recommended to use spatie/laravel-html instead. Spatie/laravel-html is a package that provides similar functionality to laravelcollective/html. It can be used to generate HTML forms and links, as well as other HTML elements.

To use spatie/laravel-html, you can follow these steps:

  1. Install the package using composer:
composer require spatie/laravel-html
  1. Add the service provider to your config/app.php file:
'providers' => [
    // ...
    Spatie\Html\HtmlServiceProvider::class,
],
  1. Add the facade to your config/app.php file:
'aliases' => [
    // ...
    'Html' => Spatie\Html\Facades\Html::class,
],
  1. You can now use the Html facade to generate HTML elements in your views:
{!! Html::link('route.name', 'Link Text', ['class' => 'link-class']) !!}

This will generate an HTML link with the specified route name, link text, and CSS class.

Similarly, you can use the Form facade to generate HTML forms:

{!! Form::open(['route' => 'route.name']) !!}
    {!! Form::text('name', null, ['class' => 'form-control']) !!}
    {!! Form::submit('Submit', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}

This will generate an HTML form with a text input field and a submit button.

Overall, spatie/laravel-html provides similar functionality to laravelcollective/html and can be used as a replacement.

hiviyan's avatar

@LaryAI

Thanks for your reply.

If I want to use ""Form" Facade for spatie/laravel-html, what should I add in 'aliases' ?

Snapey's avatar

@hiviyan Don't take Lary's answer too literally. As often happens its a confusion of bits of code scraped from unrelated sources.

The Spatie html package has a completely different syntax to Laravel Collective

Bear in mind that these are convenience helpers. They are marginally simpler than writing the html yourself.

4 likes
Xanger's avatar

@tykus This package, on the other hand, has helped me so much, because to write the selects, it saved me from writing so much html code...

{{ Form::select('id_console', array('' => 'Select console') + $console, $article->id_console?? '',  array('class' => 'form-select')) }}

instead of writing:

        <select class="form-select" name="id_console[]" id="id_console" multiple>
          @if(empty($article->id_console))
            <option value="0">Select Console</option>
            @foreach($consoles as $console)
              <option value="{{ $console->id }}">{{ $console->abb_cat }}</option>
            @endforeach
          @else
            <option value="0">Select Console</option>
            @foreach($consoles as $console)
              <option value="{{ $console->id }}"
                @foreach ($list_consoles as $list_console)
                  @if($console->id == $list_console->id)
                    selected="selected"
                  @endif
                @endforeach
                >{{ $console->abb_cat }}</option>
              @endforeach
            @endif
          </select>

Maybe there is a way to simplify the html of the select, however, the laravelcollective/html package helped a lot.

newbie360's avatar

@Xanger For me, i can't understand what this actually to do, unreadable :)

{{ Form::select('id_console', array('' => 'Select console') + $console, $article->id_console?? '',  array('class' => 'form-select')) }}

create a blade component instead, blade component more powerful

1 like
hiviyan's avatar

All, So, you guys dont use laravelcollective/html or spatie/laravel-html? If so, do you write raw HTML in .blade files? Or, do you use any other tools that you would recommend to use?

Thanks.

Tray2's avatar

@hiviyan Most of us use regular html in blade, and some create reusable blade components (which is still regular html in blade but in a component).

aleksandar777's avatar

@hiviyan spatie/laravel-html have awful documentation. In most cases you will need to go in source files to understand how to do something even not mentioned in documentation. Even simplest questions you will not find in documentation (like how to add size of text area)... {!! html()->textarea('description', null)->class('form-control')->rows(3)->cols(50) !!} or something like following: {!! html()->modelForm($customMetric,'PATCH', route('data-source-fields.updateCustomMetric', [$dataSource->id, $customMetric->id]))->id('edit-custom-metric-form')->class('fields-form-inline')->open() !!}

Most of time you will spend exploring source code of larael-html cause lack of good documentation.

github.com/spatie/laravel-html

1 like
vincej's avatar

I have been using Collective since Laravel 4.2. At that time I was a total Laravel newb and Collective was promoted as the go to solution for easy HTML inside Laravel. To date I have thousands of lines of code using Collective. So, if my application needs to be updated I need to find the easiest route forward, and so I have three questions:

  1. Does anyone know how different the spatie/laravel-html syntax is from Collective? i.e would updating from Collective to Spatie be not too bad?
  2. Does anyone know of a programmatic approach to changing Collective to raw HTML?
  3. Does anyone know if future upgrades to Laravel would make Collective incompatible with those upgrades ie are there dependancies which could break?

Many Thanks!

1 like
cwhite's avatar

@vincej

Does anyone know of a programmatic approach to changing Collective to raw HTML?

The legacy codebase I work used Collective heavily, I've been in the process of creating components for the different inputs and then gradually switching them all over

vincej's avatar

@cwhite Thanks for that. Could you elaborate a little on, maybe with an example : " creating components for the different inputs "

Many thanks!

cwhite's avatar

@vincej,

Sure, essentially you want to abstract away a lot of the duplication and styling

components/form/index.blade.php

@props([
    'method' => 'post',
    'model',
])

@php
    $method = strtoupper($method);

    $formMethod = in_array($method, ['GET', 'POST'], true)
        ? $method
        : 'POST';
@endphp

<form
    method="{{ $formMethod }}"
    {{ $attributes }}
>
    @unless ($method === 'GET')
        @csrf()
    @endunless
    @unless ($method === $formMethod)
        @method($method)
    @endunless
    {{ $slot }}
</form>

I use it as follows:

<x-form
    method="get|post|put|patch..."
    :action="route('...')"
    :model="$model" // any arrayable (optional)
>
// content or other form inputs
</x-form>

The input component are similar, I have base components (like for the input tag) and then other components that build off the base component:

E.g., my text input just defers to the base input component

<x-form.input
    type="text"
    {{ $attributes }}
/>

I use them in the following way:

<x-form.text
    name="username" // if no value is passed and the form has an arrayable model,
                   // then uses this to get value from model attribute or array key
    id="..." // if no id is passed then assumed to be same as name
    label="Username" // automatically creates a label (using label component) 
                // above the input and associates with this input
    required // optional attribute, label component automatically adds red asterisk
              // when input is required
    value="..." // when no value is passed then uses name and model to get input
               // (can also handle old input)
/>

The components are also capable of showing validation errors under each input automatically (using the name attribute)

jason-mccreary's avatar

The migration from larvelcollective/html to spatie/laravel-html is not so straightforward. While all the methods from the LaravelCollective exist within Spatie HTML, their syntax is different or, in some cases, the argument order changes.

For example:

{{--- LaravelCollective ---}}
{!! Form::label('Name', 'name_input') !!}
{!! Form::text('name', null, ['placeholder' => 'Enter your name', 'class' => 'mt-2 p-4', 'id' => 'name_input']) !!}}


{{--- LaravelCollective ---}}
{{ html()->label( 'name_input', 'Name') }}
{{ html()->text('name')->placeholder('Enter your name')->class('mt-2 p-4')->id('name_input']) }}

Since these changes aren't simple search and replace, and this package is still one of the "Top 10" most popular Laravel packages, I have made a Shift to automate the migration to Spatie HTML.

However, I agree with some of the other replies that if you aren't using this package too extensively, it may be best to simply rewrite it as native HTML or custom components.

1 like
yagrasdemonde's avatar

Hello, I want to migrate to spatie/laravel-html but how to achieve with laravelcollective custom components registered in provider ?

For example in my provider I have

Form::component('checkboxGroup','vendor.components.checkbox', ['params', 'errors']);

Attached view

<div class="form-group">
        <div class="row">
            <label for="{{ Str::slug(Arr::get($params, 'name').Arr::get($params, 'value')) }}" class="col-sm-3 col-form-label {{ $errors->has(Arr::get($params, 'name')) ? 'text-danger' : '' }}">{!! $errors->has(Arr::get($params, 'name')) ? '<i class="far fa-times-circle"></i>' : '' !!}&nbsp;{{ Arr::get($params, 'label') }}</label>
            <div class="col-sm-9">
                <div class="icheck-primary {{ Arr::get($params, 'inline', false) === true ? 'icheck-inline' : '' }}">
                    {{ Form::checkbox(Arr::get($params, 'name'), Arr::get($params, 'value'), null, ['id' => Str::slug(Arr::get($params, 'name').Arr::get($params, 'value')), 'class' => Arr::get($params, 'class'), Arr::get($params, 'required', false) ? 'required' : '']) }}
                    <label for="{{ Str::slug(Arr::get($params, 'name').Arr::get($params, 'value')) }}">
                        @if(Arr::get($params, 'labelCheckboxFile'))
                            @include(Arr::get($params, 'labelCheckboxFile'))
                        @else
                            {{ Arr::get($params, 'labelCheckbox', Arr::get($params, 'label')) }}
                        @endif
                    </label>
                </div>
                <div id="{{ Arr::get($params, 'name') }}_validate"></div>
                @if ($errors->has(Arr::get($params, 'name')))
                    <div class="invalid-feedback d-inline">
                        {{ $errors->first(Arr::get($params, 'name')) }}
                    </div>
                @endif
            </div>
        </div>
    </div>

And in view form I call this custom component like

{{ Form::checkboxGroup(['horizontal' => false, 'inline' => false, 'name' => 'rgpd', 'value' => '1', 'label' => 'Accept ? RGPD'','required' => true], $errors) }}

Thank you for your advices

smithdp1's avatar

Soooo bummed to see laravelcollective/html go! Really loved using that package. All my snippets in sublime....I could build forms so fast. What a bummer! Has anybody forked this to resume development so it will work on Laravel 12?

Please or to participate in this conversation.