1. Install and confirm the class name before writing any code.
composer require elbytes/nova-tooltip-field
This package has no README-driven API guarantees you can trust blindly (4 stars, 0 dependents, last release July 2021), so spend your first five minutes reading the source rather than guessing:
vendor/elbytes/nova-tooltip-field/src/ — the PHP field class. It will be a subclass of Laravel\Nova\Fields\Field; note the exact namespace (likely Elbytes\NovaTooltipField\...) and class name (Tooltip vs TooltipField).vendor/elbytes/nova-tooltip-field/resources/js/ — the Vue component and how it's registered in field.js.composer.json of the package — check the laravel/nova constraint and whether dist/ assets are committed.2. Make sure the compiled assets are actually served.
Nova 4 loads field assets from the package's dist/js/field.js via the Nova::script()/service-provider boot. If dist/ is missing or was built against Nova 3's Vue 2 toolchain:
cd vendor/elbytes/nova-tooltip-field && npm install && npm run prod
3. First use case: an informational tooltip in a form.
use Elbytes\NovaTooltipField\Tooltip; // verify against src/
public function fields(NovaRequest $request)
{
return [
Tooltip::make('Annual Recurring Revenue')
->withMeta(['tooltip' => 'Calculated nightly from active subscriptions.']),
];
}
The realistic day-to-day value is small but real: a read-only field that documents what another field or metric means, right where the user is looking. If your Nova version already gives you Laravel\Nova\Fields\HelpText (Nova 4) or plain Field::make(...)->help(...), use those first — this package is only worth it if you specifically want the icon-and-hover affordance.
Pair it with the field it explains. Nova renders fields in declaration order, so a tooltip field immediately followed by the real field reads as a label annotation. Constrain it with ->onlyOnForms() or ->onlyOnDetail() so it doesn't leak into the index table as an empty column.
Push text through meta, not the attribute. A tooltip field has no backing database column. Everything lives in withMeta(), and resolve() should return nothing meaningful. Never put it in a resource whose fields() result is used for index sorting or filtering.
Reuse one instance across views. Because it's pure presentation, you can build a small helper on your base resource:
protected function hint(string $label, string $text): Tooltip
{
return Tooltip::make($label)->withMeta(['tooltip' => $text]);
}
Combine with ->component() if the shipped Vue component breaks. Since the class extends Nova's Field, you keep ->component('HelpText') or expose your own TooltipField.vue registered via a custom Nova::script() call in a service provider. This is the escape hatch when the 2021 asset bundle doesn't render under Nova 4 — you get the PHP ergonomics without the stale JS.
Use it on dashboards and detail screens, not just forms. The strongest pattern is documenting derived metrics on a Detail view, where a bare Text field would otherwise show a number with no explanation.
composer require is the whole job.nova-components/ in your own app — you get the same result, no supply-chain surface, and full control.overflow constraints; a hover popover will get cut off. Restrict tooltips to detail/form views, or force ->onlyOnDetail().v-html will happily execute markup. If the package's component uses v-html, only pass trusted strings — never user-supplied content.NovaRequest; it's decoration. Validation rules on it are silently pointless.composer dump-autoload), confirm dist/js/field.js is referenced in the page source, then check the browser console for a Unknown custom element warning — that means the component name in the PHP class and the Vue.component(...) registration disagree.php artisan nova:publish, php artisan view:clear, and php artisan nova:cache/nova:clear-cache if you use Nova's field caching.->component(), ->withMeta(), and ->help() (if your Nova version has it) let you outgrow the package without removing it.How can I help you explore Laravel packages today?