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

Nova Hidden Field Laravel Package

outhebox/nova-hidden-field

A Laravel Nova field that hides attributes from forms and detail views while still submitting and storing their values. Declare defaults for auto-filled or sensitive data, keep the UI clean, and persist values without custom JavaScript or resource workarounds.

View on GitHub
Deep Wiki
Context7

Getting Started

Install it alongside Nova and confirm it actually works on your Nova major before you build anything on top of it:

composer require outhebox/nova-hidden-field

There is no config to publish, no migration, and no asset build step — the service provider is auto-discovered. The entire package is one PHP field class (src/Hidden.php) plus a trivial Vue component. Read both once; that is your whole dependency surface.

The gating step is compatibility. The last release was 2020-05-20, predating Nova 4 and 5, and laravel/nova is not on Packagist, so Composer cannot block an incompatible install. Prove it first: drop the field into a resource, load the create form, and check that (a) the browser console shows no "unknown component" warning and (b) an <input type="hidden"> is present in the DOM with your default in it. If either fails, stop and write the field in-house — it is roughly 30 lines.

The first real use case is a column a human should never choose — user_id, tenant_id, created_by, source:

use Outhebox\NovaHiddenField\Hidden;

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Title'),
        Hidden::make('User ID')->default(auth()->id()),
    ];
}

Because it renders as a normal hidden input inside the Nova form, the default rides along with the standard create/update request. No custom controller, no fillUsing for the simple case.

Implementation Patterns

Create-time stamping. Hidden::make('User ID')->default(auth()->id()) is the canonical shape. Add ->rules('required', 'exists:users,id') when a missing value would corrupt data, so it fails loudly instead of silently writing null.

Ambient request data. Anything the request can see is fair game: ->default(request()->ip()), ->default(request()->header('X-Campaign')), ->default(session('affiliate')). This is where the field beats a model event — the value travels with the Nova form submission rather than being reconstructed server-side.

Carry a computed key for a visible field. Store Str::slug($request->input('title')) in a slug column while the editor only touches the title. The hidden field keeps the value in the payload so it is set on create without a separate endpoint.

Recompute on every save with fillUsing(). ->default() only applies when the field has no existing value, so on edits the stored model value wins. When a value must be refreshed each save:

Hidden::make('Updated By')
    ->default(auth()->id())
    ->fillUsing(fn ($request, $model) => $model->updated_by = auth()->id());

Per-operation resources (Nova 4+). Prefer fieldsForCreate() / fieldsForUpdate() over branching inside one fields() method, and attach the hidden field only where it has a job. Keeps the update path clean.

Keep it off index and detail. Verify it is suppressed on index/detail; if it shows up as a blank column, chain ->hideFromIndex() / ->hideFromDetail() explicitly.

Group attribution metadata. Several hidden fields in one resource (source, campaign, referrer) is a cheap way to capture attribution without a custom Nova tool — all the logic stays readable in one fields() method.

Validation is the real contract. A hidden input is still client-supplied and trivially editable through devtools. Treat ->rules() as the authoritative check, and derive anything security-sensitive server-side in fillUsing() rather than trusting a posted default.

Gotchas and Tips

  • Defaults only apply when the field renders. If you suppress it (->hideFromCreate(), ->onlyOnDetail(), ->hideWhenCreating()), Nova never mounts the component, so ->default() never reaches the request and the column ends up null. Hidden does not mean omitted — the value needs a rendered hidden input to be submitted at all.
  • ->default() does not overwrite on update. The most common surprise for developers coming from model events. Use ->fillUsing() or a saving model event when the value must be recomputed every save.
  • Actions and non-UI paths bypass it entirely. Nova actions, nova:run commands, imports, seeders, and direct API writes never touch the field. Keep authoritative logic in the model or a service; treat this as a convenience for the Nova UI path only.
  • ->rules('required') on a hidden field bites in non-UI paths. Validation fails on any request where the component did not render — a classic "why is this action erroring?" bug. Prefer sometimes / nullable unless you have confirmed every render path.
  • Debugging. Temporarily swap Hidden::make(...) for Text::make(...) (or add ->showOnDetail()) to see whether the default is actually populated. Dump $request->all() in a throwaway fillUsing closure to confirm the field is in the payload. If it is missing, the component did not mount — check the console for a registration warning.
  • Extension points are thin. No config, no documented hooks. Real customisation happens through the standard Nova Field chain (fillUsing, resolveUsing, withMeta) or by forking the class. There is no conditional visibility here — despite the description, this is a hidden input, not a reactive show/hide engine. If you need conditional fields, you are writing that yourself.
  • Prefer model events for critical invariants. If losing the value would corrupt data — audit trails, ownership, tenant scoping — set it in booted() / saving on the model and use the hidden field only for UI conveniences where a missing value degrades gracefully.
  • Treat it as a snippet you copy, not a dependency you inherit. Zero dependents, a 2020 release, no security patch path. When you need anything beyond "put this value in the payload on create," vendor the class into your codebase, own it, and move on — do not extend it.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core