izi-dev/nova-conditional-field
Before you install, verify the package identity. The Composer name (izi-dev/nova-conditional-field) and the repository name (izi-dev/nova-conditional-if) don't match, which is a common source of "package not found" confusion. Check the README and composer.json on the repo to confirm the exact require string and the supported Nova major version (Nova 3 and Nova 4 field APIs differ enough that this matters).
Minimal steps:
composer require izi-dev/nova-conditional-field
php artisan nova:publish # only if the package ships assets/config
Register the field in a NovaResource and confirm it renders before wiring anything real:
use IziDev\NovaConditionalField\ConditionalField;
ConditionalField::make('Plan')
->options([...]),
Where to look first, in this order:
README.md — method names and the canonical example. Assume the docs are the only spec; there are no dependents (0) and only 16 stars, so there is no ecosystem of blog posts or Stack Overflow answers to fall back on.src/ — the field class (what component() it resolves to, what meta() it sends to Vue) and any trait/concern it uses.resources/js/ — the Vue component. This tells you exactly whether hidden fields are unmounted, v-show-hidden, or still submitting — which determines your validation strategy (see Gotchas).First use case to build: the classic "Other" pattern. A Select with an other option should reveal a free-text field only when selected:
Select::make('Source')
->options(['web' => 'Web', 'referral' => 'Referral', 'other' => 'Other']),
ConditionalField::make('Source Detail')
->dependsOn('source', 'other'), // verify exact signature in README/src
Ship this one field to production first. If the conditional logic behaves, the rest of your usage is repetition; if it doesn't, you've spent an afternoon, not a sprint.
Treat it as a form-UX layer, not a validation layer. The single most important pattern: conditional visibility and conditional validation are separate concerns. The field hiding is client-side; your FormRequest/->rules() still runs against whatever the browser posts. Always pair visibility rules with explicit server-side rules:
Select::make('Source')->options([...])->required(),
ConditionalField::make('Source Detail')
->dependsOn('source', 'other')
->rules('required_if:source,other', 'max:255')
->hideFromIndex(),
That required_if is your real safety net — it works even if JS fails, the user has JS disabled, or a stale tab posts an older form state.
Dependency chains and multi-field conditions. Most conditional-field packages support "show when field A is X and field B is Y," but the API for that is exactly where small packages diverge (array of [field, value] pairs vs. fluent chaining vs. a closure). Read src/ before designing a form around three-way conditions — don't assume the README's two-field example scales. If it only supports a single dependency, compose it: build the compound condition on a hidden Select/Boolean you compute server-side in fields() and depend on that.
Keep the dependency graph shallow. Conditional fields that depend on fields which are themselves conditional become hard to reason about and harder to debug when a field silently never appears. A flat structure — one "controller" select driving two or three dependents — covers most real admin UIs.
Integration with the rest of the resource. Conditional visibility is a form concern. Explicitly call ->hideFromIndex() / ->hideFromDetail() (or ->onlyOnForms()) on the dependent fields, otherwise you'll get a half-empty index table and a detail page full of blank rows. For index/detail conditionality you need a different tool entirely (computed fields, ->displayUsing(), or a custom Text field resolving a closure).
Extract repeated conditions. If the same "is this a company account?" condition gates four fields, wrap it in a private method on the resource or a small base class:
private function isCompany(): string { /* returns the field name or condition */ }
Small packages like this one rarely have a "named condition" feature; building that abstraction yourself costs ten minutes and saves you when you swap the package out.
Have an exit plan baked in. Because this is a 16-star package with zero dependents, write the usage so it's replaceable: keep conditional logic out of your models, don't let the conditional field class leak into Actions or Jobs, and confine it to fields() methods. If you're on Nova 4, evaluate whether Nova's own field-dependency features cover your case before adding a dependency at all.
Hidden ≠ not submitted. Inspect resources/js/ to learn whether the dependent field is v-if'd out (value is lost) or merely visually hidden (value is submitted, possibly stale). This decides whether your controller needs to null out source_detail when source !== 'other' — a very common bug: user selects "other", types detail, switches back to "web", and a detail value you never wanted persists in the DB.
Validation runs against hidden fields. If a hidden field is ->required() unconditionally, the form will fail to save with an error the user cannot see. This is the #1 support ticket with conditional fields. Always express requirements as conditional rules (required_if, required_with, prohibited_if) rather than toggling ->required() on the field object, which is evaluated at build time, not at submit time.
Nova version compatibility is the main risk. With no dependents, there's no one else to have hit the Nova 4/5 breakage for you. Pin the version in composer.json, and after any composer update or Nova upgrade, click through every form using the field. Check the repo's last-commit date before you commit — an unmaintained Nova 3 package will cost you more in migration time than writing the field yourself.
Asset build problems look like logic bugs. If the field renders as a plain input or not at all, it's almost always unpublished/unbuilt assets, not your dependsOn. Debug in this order: (1) browser console for a failed Vue component resolution, (2) whether vendor/izi-dev/.../dist/js exists, (3) whether the published package JS is stale after a Nova upgrade. php artisan nova:publish --force and a hard browser refresh resolve most of it.
Watch out for dependsOn naming collisions. Nova itself has dependency-related APIs in newer versions; if the package hijacks a common method name, you can get confusing double behavior. Grep the field class for the method to confirm it's the package's implementation, not Nova's.
Debugging visibility. Add a temporary ->help() or ->withMeta(['debug' => true]) and log the meta the field sends down (meta() in the PHP class) — if the value the JS compares against is a string "1" versus integer 1, your condition will never fire. Type coercion between the select's value and the compared value is the second most common failure after validation.
Extension points to prefer. If the package publishes config or views, publish and own them rather than editing vendor/. If it doesn't, keep your customizations in a subclass of the field so a composer update can't silently overwrite your fixes — and so you can fork the package into packages/ later without touching every resource.
How can I help you explore Laravel packages today?