Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Html Laravel Package

konekt/html

Konekt HTML is a fluent tag and form builder for Laravel. Generate HTML elements, Bootstrap-friendly forms, and reusable macros directly from PHP, with clean chainable APIs that keep markup out of your templates.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and confirm the framework constraint first. konekt/html is a community continuation of the old laravelcollective/html package (itself the package removed from Laravel core in 5.0), so the single most important first step is checking the illuminate/* constraints in composer.json against your Laravel version:

composer require konekt/html
composer show konekt/html   # read the illuminate/* requirements

If composer update resolves but your app is on a newer Laravel major than the package declares, expect silent breakage in edge cases (session/old-input handling, Blade directives) — verify on a branch before adopting.

Register the provider/facades. Modern releases use package auto-discovery; on older apps or after a Laravel upgrade you may still need:

// config/app.php
'providers' => [Konekt\Html\HtmlServiceProvider::class],
'aliases'   => ['Form' => ..., 'Html' => ...],

Check the README for the exact class names in your installed version — the facade paths have moved between the Collective\Html and Konekt\Html namespaces.

Publish the config (class injection defaults, component defaults) if you're not on Bootstrap:

php artisan vendor:publish --provider="Konekt\Html\HtmlServiceProvider"

First use case: replace a hand-written <form> in a resource controller's create/edit view with a model-bound form. That single change gives you CSRF, method spoofing, old-input repopulation and model hydration for free, which is where 90% of the package's value lives.

{!! Form::model($post, ['route' => ['posts.update', $post], 'method' => 'PUT']) !!}
    {!! Form::text('title', null, ['class' => 'form-control']) !!}
    {!! Form::textarea('body', null, ['rows' => 8]) !!}
    {!! Form::submit('Save', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}

Implementation Patterns

Model-bound CRUD forms. Form::model() is the canonical pattern: pass the Eloquent model as the second argument and the builder fills every field from the attribute (or old() on a validation redirect) unless you explicitly pass a non-null value. Pair with a FormRequest for validation and a resourceful controller — the view needs almost no glue code.

Error-aware field partials. Rather than repeating Bootstrap/Tailwind error classes, create one partial per control and drive it from $errors:

{{-- resources/views/components/form/text.blade.php --}}
<div class="form-group {{ $errors->has($name) ? 'has-error' : '' }}">
    {!! Form::label($name, $label) !!}
    {!! Form::text($name, $value, array_merge(['class' => 'form-control'], $attributes)) !!}
    @if($errors->has($name)) <span class="help-block">{{ $errors->first($name) }}</span> @endif
</div>

Register custom components for repeated markup. The builder has a component() method that binds a partial to a macro name, so {!! Form::bsText('title', 'Title') !!} expands to your view:

// AppServiceProvider::boot()
Form::component('bsText', 'components.form.text', ['name', 'label', 'value' => null, 'attributes' => []]);

The argument list order must match how the partial consumes variables; add defaults for optional args or every call site gets brittle.

Macros for everything the component system can't express. Form::macro('money', fn($name) => ...) is the escape hatch for one-off controls and for wrapping JS-driven widgets. Register them in a dedicated FormServiceProvider rather than AppServiceProvider once you have more than two or three.

Selects from Eloquent. Form::select('author_id', User::pluck('name', 'id'), null, ['placeholder' => 'Choose…']) works well; for many-to-many relationships pass the plucked array and an array of selected IDs — model binding will not resolve pivot relations for you.

Static assets stay out of this. Html::script/Html::style exist for parity, but on any app using Vite or Mix, keep the asset pipeline in Blade's @vite/mix() helpers and reserve the HTML builder for structural helpers (Html::link, Html::ul, Html::attributes) where it actually saves typing.

Testing. Assert against rendered attribute strings (assertSee('name="title"', false)); note that any test touching the facades needs a booted application, so keep form assertions in Feature tests, not plain Unit tests.

Gotchas and Tips

  • Escaping. The builders return raw HTML; {{ Form::text(...) }} will print escaped markup. Always {!! !!}. Newer releases ship shorthand Blade directives (@form … @endform) that hide this; check your version's docs before using them, since mixed Blade versions in one codebase are a debugging hazard.
  • Checkbox / radio submission. Unchecked boxes send nothing, so old() and model binding both see them as "missing" rather than false. Emit {!! Form::hidden('active', 0) !!} immediately before the checkbox to get deterministic booleans.
  • Value precedence. Form::text('name', $value) — a non-null $value wins over both the model attribute and old() input. Passing '' instead of null silently disables repopulation after a failed validation; this is the most common "why is my form blank after validation?" bug.
  • Config-injected classes. If the published config adds Bootstrap classes, a Tailwind or custom-design-system app gets double-styled inputs. Publish the config early and override it, or the package's defaults will leak into every form.
  • Facade aliases after upgrades. Auto-discovery usually handles this, but on legacy apps the Form/Html aliases are the first thing to break after a Laravel major bump. Symptom: Class "Form" not found in Blade only.
  • Deep customization is a container binding. The provider binds 'form' and 'html' singletons; to swap in a subclass, use $this->app->extend('form', fn($builder, $app) => new CustomFormBuilder(...)) from a provider that registers after HtmlServiceProvider.
  • Version drift is the real risk. With 26 stars the package tracks Laravel majors on a best-effort basis. Pin it in composer.json, run your full suite against a new Laravel release on a branch, and keep a fork ready — the package surface is small (two builders plus facades), so vendoring is cheap if you need a same-day fix.
  • Debugging. dd(Form::getModel()) inside the form block confirms what the builder is bound to; if fields are unexpectedly empty, that's the fastest way to distinguish "wrong model" from "value-precedence bug".
  • CSRF in edge cases. Form::open() embeds a token by default; for stateless or signed-URL forms pass ['url' => ..., 'method' => 'POST'] and consider disabling the token explicitly rather than stripping it after the fact.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo