datomatic/nova-charcounted-fields
Nova Char Counted Fields adds text and textarea fields to Laravel Nova with a live character counter, optional maxlength enforcement, and configurable limits—helping you keep content within length requirements in your admin panels.
v2.0.0 is scoped entirely to Nova 4 compatibility. That is a small sentence with large implications: Nova 4 moved to Vue 3 + Inertia, dropped vue-router from the SPA shell, and switched asset compilation to the laravel-nova Mix helper. If the package ships compiled dist/ assets, the bump is mostly a composer constraint change. If it ships source only, your build toolchain changes.
Look at these four things first, in order:
composer.json — the laravel/nova constraint. v2 should be ^4.0 (or ^3.0|^4.0 if the package maintains one branch for both). A stale * or ^3.0 constraint is the most common cause of "I upgraded and nothing changed".boot() — where Nova::script(), Nova::style(), Nova::mainMenu() and Nova::serving() are called. This tells you whether the package is self-registering or requires you to wire it into NovaServiceProvider.nova.mix.js / webpack.mix.js and resources/js/ entry point — confirms whether you need laravel-nova in your package.json and a npm run dev step.dist/ directory in the tagged release — if it is committed, you can composer update and skip the front-end build entirely.Minimal path to a working install on Nova 4:
composer require laravel/nova:^4.0 vendor/package:^2.0
php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" --tag=package-assets
php artisan nova:publish
php artisan optimize:clear
Then register the card/tool in app/Nova/NovaServiceProvider.php (cards() / tools()) or use the field directly in a resource's fields() method, and load /nova to confirm it renders.
First use case: the fastest signal that the upgrade worked is a card or field already in your Nova dashboard. If those render, the Inertia/Vue 3 plumbing is sound; multi-page tools are the part most likely to need rework.
Keep both majors installable while you migrate. The pragmatic constraint for a package that supports both is "laravel/nova": "^3.0|^4.0", with a runtime split where APIs diverge:
if (class_exists(\Laravel\Nova\Menu\Menu::class)) {
Nova::mainMenu(fn ($request) => (new Menu)->append(...));
}
Nova 3's menu building (Nova::tools() + Tool::menu()) and Nova 4's Nova::mainMenu() closure are not interchangeable, so version-gate at the provider, not inside the components.
Register front-end assets in boot(), never in register(). Nova::script()/Nova::style() queue assets consumed during the Nova request lifecycle. Use a stable handle so you can reason about ordering:
Nova::script('vendor/package', __DIR__.'/../dist/js/package.js');
Nova::style('vendor/package', __DIR__.'/../dist/css/package.css');
Component registration follows the standard Nova 4 booting event. In the package entry point:
Nova.booting((app, store) => {
app.component('vendor-package-card', require('./components/Card.vue').default)
})
The component name must match the PHP-side $component property exactly — this is the single most common "blank card" failure.
Multi-page tools: replace this.$router with Inertia. Any navigation code carried over from v1 needs this.$inertia.visit(url) or Nova.visit(url). Tool routes still live behind the nova middleware group under a nova-vendor/ prefix, so backend routing is unchanged; only the front-end navigation primitives moved.
Gate visibility server-side. Tool::canSee(fn ($request) => $request->user()->isAdmin()) and authorize() closures are the right place for per-role gating; doing it in Vue just ships the component to users who can't use it.
Test both majors in CI using a Testbench matrix plus a path repository for the package, or accept that the Nova 4 branch is manually verified. Nova's composer package is behind credentials (composer config http-basic.nova.laravel.com), which is the usual reason these matrices get skipped — plan for a manual smoke test on each release rather than assuming coverage.
Pin the major in consuming apps. "vendor/package": "^1.0" if you're on Nova 3 — Composer will happily pull v2.0.0 otherwise, and you get a package expecting a front-end runtime you don't have.
composer update succeeds, but if the host app still resolves laravel/nova:^3.0 the new code paths never run. Check with php artisan nova:version (or composer show laravel/nova) before debugging anything else.this.$parent chains, $listeners, component-level $on/$off, filters, and v-model on custom components (value/input → modelValue/update:modelValue) all changed. The Nova.$on/Nova.$emit global event bus still exists; the component-level one does not.Nova::script() handle never ran (wrong provider, register() instead of boot(), or an unpublished asset) or a component name mismatch between PHP and JS.php artisan nova:publish --force — Nova's compiled assets and the published package assets are separately cached, and browsers cache app.js aggressively. Use a hard reload before filing a bug.vendor:publish overwrites your customizations. If you edited the published config or views, diff them against the new release before publishing. --force is not your friend on a first upgrade.Nova::mainMenu() free of DB queries and heavy container resolution; it is not cached the way config is.NovaServiceProvider alongside the new auto-registration), you get duplicate component warnings and occasionally two copies of the same card./nova-api/... network responses → Nova::version() → whether dist/ exists in vendor/. That order resolves most issues in under five minutes.Tool::boot() for setup that must run before routes; the nova:: view namespace for overriding package views without touching vendor/; and Nova::script/Nova::style for adding your own assets alongside the package's.The overall read: v2.0.0 is a compatibility release, not a feature release. The migration risk is concentrated in the front-end runtime, not the PHP API. Budget your effort for the Vue 3 and Inertia adjustments, and keep Nova 3 consumers pinned to v1 until they move.
How can I help you explore Laravel packages today?