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 Email Field Laravel Package

inspheric/nova-email-field

A Laravel Nova field for displaying and editing email addresses with built-in validation, clickable mailto links, and a clean interface. A simple drop-in upgrade for the default email field that improves UX in forms and index views.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and confirm what you actually got. There is no config to publish, no migration, and no schema change — the underlying column stays a string.

composer require inspheric/nova-email-field

Before wiring it into a resource, read three files in the vendor directory (it takes two minutes and answers 90% of your questions):

  • vendor/inspheric/nova-email-field/composer.json — the Nova, Laravel, and PHP constraints. This is the fastest way to catch a mismatch, because the last release is v2.0.1 (2022-11-28) and predates current Nova majors.
  • vendor/inspheric/nova-email-field/src/Email.php — which Nova field class it extends and which meta keys drive index vs. detail rendering. This is your debugging reference for the rest of the project's life.
  • vendor/inspheric/nova-email-field/README.md plus the GitHub releases — confirm you are on the 2.x line and whether v2.0.1 is what Composer resolved.

Pin the version line you land on (composer require inspheric/nova-email-field:^2.0) so an unattended composer update cannot silently move you.

First use case: swap Text::make('Email'). It is a drop-in replacement — the same modifiers work, and validation is your responsibility:

use Inspheric\EmailField\Email;

public function fields(Request $request)
{
    return [
        Email::make('Email', 'email')
            ->rules('required', 'email', 'max:255')
            ->sortable()
            ->searchable(),
    ];
}

On index and detail views the value renders as a mailto: link (with copy-to-clipboard support); on forms it is a plain text input. That asymmetry is the whole point of the package — everything else is standard Nova.

Implementation Patterns

Treat it strictly as a presentation layer. The field renders a mailto: link; it does not validate, normalize, or verify anything. Keep your rules explicit and keep domain logic out of the field:

Email::make('Email')
    ->rules('required', 'email:rfc,dns', 'max:255');

If you need deliverability, MX checks, or verification workflows, those belong in a form request, a job, or a dedicated service — not here.

Display-only in listings, editable where it matters. The most common day-to-day pattern is read-only on index/detail and editable only on forms:

Email::make('Email')
    ->rules('required', 'email')
    ->sortable()
    ->searchable()
    ->hideWhenCreating()
    ->hideWhenUpdating();

And the inverse, when an address should be captured once at creation and never touched again:

Email::make('Email')
    ->rules('required', 'email')
    ->hideFromIndex()
    ->hideFromDetail();

Reuse the standard Nova modifiers rather than writing custom code. The package adds nothing here, so all the usual affordances apply:

Email::make('Email')
    ->onlyOnDetail()
    ->canSee(fn ($request) => $request->user()->isAdmin())
    ->help('Primary contact address — changes are logged.');

That canSee pattern is worth reaching for early on PII-adjacent resources: an email column visible to every Nova user is usually a review finding waiting to happen.

Rollout across many resources is a find-and-replace — with a catch. Swapping Text::make('Email') for Email::make('Email') is mechanical, but every field's chained modifiers live on that line, so diff each one. Grep is your friend:

grep -rn "Text::make(.*[Ee]mail" app/Nova/

Custom rendering: prefer Nova's APIs over editing vendor code. displayUsing() is a clean escape hatch for formatting or a subject line:

Email::make('Email')
    ->displayUsing(fn ($value) => $value ? "mailto:{$value}?subject=Account%20Enquiry" : null);

Keep in mind that a heavy displayUsing() callback on the index view runs per row — fine for a few hundred records, worth watching on large tables.

Index click behaviour is the thing to design around. Since v2.0.1 the mailto link calls stopPropagation, so clicking the address opens the mail client without also navigating to the record. That is deliberate and generally what you want, but if your resource relies on "click anywhere in the row to open," operators will now need to click a non-email cell. Document it for the ops team, and check any custom row-level JS.

Outside a resource, verify before depending on it. Action fields and tool forms can differ from resource rendering. Read src/Email.php and test in staging rather than assuming parity.

Gotchas and Tips

  • Nova compatibility is unproven, not merely old. Zero dependents and a 2022 release mean nobody is publicly exercising this against current Nova/Laravel/PHP. Check the constraint, branch, and test. A Nova major can change asset build requirements even when the PHP API looks unchanged.
  • v2.0.1 changed index click behaviour. The mailto link now stops propagation. Any QA script, Playwright test, or custom JS listener that relied on clicking the email cell to open the record will break — click elsewhere in the row instead.
  • The propagation fix lives in a compiled asset bundle. After install or upgrade, run php artisan nova:publish and rebuild assets. A stale bundle makes the upgrade look like it did nothing — this is the single most likely "it's broken" false alarm.
  • Validation is never automatic. Rendering a mailto: link validates nothing. ->rules('email') or a form request is still required, and email:rfc,dns is a better default than bare email if the address matters.
  • mailto: links depend on client configuration. On a machine with no default mail handler, the click does nothing — and because propagation is stopped, it goes nowhere at all rather than falling through to the row. Keep the address visible so it can be copied manually, and don't remove the copy affordance.
  • Clipboard needs a secure context. Copy-to-clipboard works reliably over HTTPS in modern browsers only. If your Nova instance sits behind plain HTTP on an internal box, test the copy button there specifically — that is exactly the environment where it silently fails.
  • sortable() and searchable() are your database's job. The field adds no query behaviour. They work only when the column exists and is queryable; on a computed or JSON-extracted attribute they will misbehave.
  • Multiple addresses are an awkward fit. Comma-separated values produce invalid mailto: links. Fall back to displayUsing() or write a small dedicated field.
  • Never edit vendor files. Extend the field class or use displayUsing(); otherwise your next composer install wipes the fix and you will not remember why.
  • Debug by reading src/Email.php first. Confirm the parent Nova field and the meta keys controlling index vs. detail output, then compare against the release notes for your installed version. A five-minute read beats an afternoon of guessing.
  • Have the fallback costed before you commit. A plain Text field with displayUsing(fn ($v) => $v ? "mailto:{$v}" : null) covers the core case with zero third-party dependency; you would only need to add your own @click.stop in a tiny custom component to match the v2.0.1 index behaviour. Given the package's age and adoption, treat this as prior art or a fork candidate — if it enters your stack, give it a named owner and a line on the Nova upgrade checklist.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log