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 Fields Laravel Package

64robots/nova-fields

A handy collection of custom field types for Laravel Nova, adding ready-made inputs like currency, country, phone, email, URL, percentage, and more—so you can build admin panels faster without writing your own fields.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm the two hard prerequisites before typing a command. This package is a set of Nova field components — it does nothing outside a licensed Nova install, and its components are compiled against a specific Nova front-end contract. Read the require block of the package's composer.json first: the laravel/nova constraint and the PHP constraint are your compatibility gate, and they are the whole reason a composer update can break your admin panel silently.

composer require 64robots/nova-fields

Pin it explicitly in composer.json. Field packages are coupled to Nova's internals, not a public API, so a caret range is a production hazard:

"64robots/nova-fields": "1.2.3"

There is no service provider to register, no config to publish, no migration, and — because the Vue components ship precompiled — no npm install / npm run build. composer install is the entire build step.

Where to look first, in this order:

  1. src/ — the authoritative field classes and their available setters. README snippets drift between tags; the class methods do not.
  2. resources/js/components/ — what actually renders and which props it accepts. This is the real API surface, and it is the only reliable way to answer questions like "does Percent store 50 or 0.5?" or "what are the label setter names on Boolean?"
  3. composer.json — Nova and PHP constraints.
  4. README.md — copy-paste starting snippets, treated as illustrative only.

First use case. Pick a single, low-stakes field on an internal resource and prove the full round trip — form render, detail render, save, reload, index. Don't adopt the bundle wholesale on day one. A Currency field on an invoice amount is a good pilot because the failure mode is visible:

// app/Nova/Resources/Invoice.php
use NovaFields\Currency; // verify the namespace in src/ before trusting this

public function fields(NovaRequest $request)
{
    return [
        ID::make()->sortable(),

        Currency::make('Amount')
            ->currency('USD')
            ->rules('required', 'numeric', 'min:0'),
    ];
}

Success criteria: renders cleanly in form and detail, index shows formatted output, browser console is empty, and the value survives save → reload unchanged. Only then add the second field.

Implementation Patterns

Declare fields per resource, adopt per field. There is no package-level registration; every field is just another entry in fields(). That makes adoption incremental and rollback a one-line revert. Keep a short docs/nova-fields.md listing which of the package's fields are sanctioned and where they're used — otherwise the next engineer either rediscovers the pattern or assumes the whole bundle is approved.

Wrap in thin local subclasses rather than importing package classes everywhere. This is the pattern that keeps your exit path open:

// app/Nova/Fields/Money.php
namespace App\Nova\Fields;

class Money extends \NovaFields\Currency
{
    public function __construct($name, $attribute = null, $resolveCallback = null)
    {
        parent::__construct($name, $attribute, $resolveCallback);

        $this->currency(config('shop.currency', 'USD'))
             ->step(0.01)
             ->rules('numeric', 'min:0');
    }
}

Swapping to a native field or an in-house component later becomes a one-file change instead of a grep across forty resources. Use it for configuration and defaults only — never put business logic here, because subclassing becomes copy-paste debt the moment upstream changes.

Prefer Nova's fillUsing / resolveUsing for anything domain-specific. Currency normalization to minor units is the classic case:

Money::make('Amount')
    ->resolveUsing(fn ($value) => $value / 100)
    ->fillUsing(function ($request, $model, $attribute) {
        $model->{$attribute} = (int) round($request->{$attribute} * 100);
    }),

Keeping the write path in your own resource is what makes a later data audit possible. It also means the field's own formatting can't quietly change what lands in the database.

Use Nova's built-in modifiers before reaching for package options. ->sortable(), ->onlyOnForms(), ->hideFromIndex(), ->readonly(), ->default(), ->help(), ->rules(), and Panels all work normally. Most "this field needs to behave differently here" requirements are solved by these, not by the field class.

Build the resource with native fields first, then fill gaps. Nova core has absorbed a lot over the majors. Compose the screen with stock fields, then add from this package only what's genuinely missing — Daterange and Wysiwyg are usually the real gaps; Boolean and Number often are not.

Sequence validation deliberately. If a field transforms input on save (Currency rounding, Wysiwyg sanitization, Daterange splitting), your rules must pass against the post-transform value, and the column must be sized for it — money as integer minor units, not float; dates as real DATE columns so they're queryable; rich text as TEXT/LONGTEXT with the same sanitization applied on output.

Treat Wysiwyg output as untrusted HTML everywhere except the edit form. Store the HTML, but render it through your own sanitizer (or {!! !!} only after purifying) in the front end, in emails, and in any Nova detail view that echoes it. On the index page, render a plain-text summary via a computed field rather than dumping HTML into a table cell.

Pin Daterange to how you actually query. Confirm from src/ whether it maps to one attribute or two. If it maps to a single attribute, you're storing JSON and losing whereBetween — in that case wire it to two DATE columns with resolveUsing/fillUsing and keep the column pair as the source of truth.

Gotchas and Tips

Nova major alignment is the whole ballgame. The components are precompiled against a Nova front-end build. A Nova upgrade without a matching package release shows up as blank fields, missing props, or console errors — silently, in the admin panel, after deploy. Put "re-verify nova-fields against the new Nova major" as a named line item in your upgrade runbook, and treat a full Nova major without a package release as a reason to fork or drop it.

The README and the source disagree about what ships. Documentation references circulate for fields (Slug, Country, Google Places) that may not exist in your pinned tag. Never add a field to a resource from a README snippet alone — open src/, confirm the class exists, and confirm the setter methods you're calling exist on it. If a field genuinely isn't there, a custom Nova field via php artisan nova:field is the honest answer.

Write-transforming fields are data-quality events. Currency normalization and any slug-ish generation change what lands in the database without throwing an exception. Before widening rollout, run a before/after audit on a sample of records, verify existing rows still render correctly on detail/edit, and write down the rollback.

Currency and Percent both have a units ambiguity — resolve it in writing. Decide once whether you store 12.34 or 1234, and whether Percent stores 50 or 0.5. Mixed conventions across resources are invisible until a report is off by 100×. Same discipline for rounding: round once, on write, with a documented mode.

Boolean fields and nulls. A tri-state column (null / true / false) will render as one of your labels regardless. If "unset" is meaningful, either add an explicit default or use a native field that reflects null honestly.

TinyMCE and asset loading. The editor pulls its own JS. On a CSP-restricted or air-gapped deployment, a CDN-hosted bundle will fail as an empty textarea with a console error. Check resources/js/components/ for how the editor is loaded, and self-host if you have a strict policy.

After install or upgrade, republish and clear. Run php artisan nova:publish, then clear config, view, and route caches. If a field renders as raw text or an empty div, the component isn't resolving — check the browser console, then compare the class's component name against what's actually in dist/.

Debugging order. (1) Browser console — component resolution and prop errors surface here first; (2) network tab — confirm the field's JSON payload from the resource endpoint carries the props you expect; (3) storage/logs/laravel.log for PHP-side resolution and validation failures; (4) scaffold a known-good native field with php artisan nova:field and diff behaviour.

You are the QA. With effectively no dependent base and a single-maintainer release cadence, edge cases get discovered by you, on your data, in production. Keep the version pinned, put the package on a periodic dependency-review cadence (watch PHP and Laravel minor drift, not just Nova), and keep all customization at the resource and wrapper-class layer — never patch vendor/. The realistic posture is "we own the fork"; make sure that's an accepted decision before, not after, the first field ships.

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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons