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 Cpf Cnpj Field Laravel Package

r64/nova-cpf-cnpj-field

A Laravel Nova field for Brazilian CPF and CNPJ tax IDs, with input masking, validation, and formatted display in Nova forms and resources. Simplifies adding and managing CPF/CNPJ fields in admin panels.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Laravel Nova field that adds a Brazilian CPF/CNPJ input — typically a masked text field with check-digit validation, formatting on display, and digit-only storage. With 1 star and 0 dependents, treat it as a small utility you will likely own rather than a supported dependency. Verify the source before adopting.

Minimal steps:

  1. Audit the repo first. Open composer.json (supported Nova/PHP versions), src/, and the compiled dist/js assets. A Nova field is just a PHP Field subclass plus a Vue component, so a 200-line repo is readable in ten minutes. Confirm it declares a Nova version constraint compatible with yours (Nova 4 uses Laravel\Nova\Fields\Field with a different asset registration path than Nova 3).
  2. Install into the app (not a shared lib) since it is unlikely to be well-maintained:
    composer require r64/nova-cpf-cnpj-field
    php artisan vendor:publish --provider="..." # only if a provider/config exists
    
    If it is not on Packagist under that name, add the GitHub repo as a VCS repository in composer.json.
  3. Look first at the field class constructor signature and the Vue component's field.value handling — that tells you whether it stores masked (123.456.789-09) or raw digits, which drives everything downstream.
  4. First use case: a Customer resource with one cpf_cnpj column.
    use R64\NovaCpfCnpjField\CpfCnpj; // verify actual namespace
    
    CpfCnpj::make('CPF/CNPJ', 'cpf_cnpj')
        ->rules('required', 'max:18')
        ->hideFromIndex(),
    
    Then submit the form once and inspect the persisted value in Tinker. Do this before writing any other code.

Implementation Patterns

Normalize on write, format on read. The cleanest day-to-day pattern with any CPF/CNPJ field is a single source of truth: store digits only in the database, mask only in the UI.

// Model
protected function cpfCnpj(): Attribute
{
    return Attribute::make(
        set: fn ($v) => preg_replace('/\D/', '', (string) $v),
        get: fn ($v) => $v, // keep raw for API/consumers
    );
}

If the field's Vue component already strips punctuation, do not double-handle it — verify and then rely on it. If it does not, wrap with ->fillUsing() or the model mutator above.

Validation belongs server-side, not just in the component. Nova fields' client-side mask/validation is a UX nicety; the request can bypass it. Mirror the rule set:

->rules('required', 'string', 'max:18', new CpfOrCnpj) // your own Rule object

Write the check-digit logic yourself (~30 lines) or pull laravel-validation-rules/cpf-cnpj. This also gives you a reusable rule for FormRequests and seeders.

One column vs two. CPF and CNPJ are different lengths and semantics. If you need to distinguish a person from a company (tipo_pessoa), store cpf_cnpj plus a derived type field, or two nullable columns. The single-column approach is simpler for search but complicates "is this a company?" queries — decide before migrating.

Display by context:

CpfCnpj::make('CPF/CNPJ')
    ->rules(...)
    ->sortable()            // only if the DB column is digits-only
    ->hideFromIndex()       // masks make index columns noisy
    ->help('Somente números ou com máscara'),

sortable() on a masked column sorts lexically, not numerically — almost always wrong. Sort on the raw column.

Pair with unique carefully. unique:customers,cpf_cnpj will only work if the stored value is normalized to digits. Otherwise 123.456.789-09 and 12345678909 both pass. Normalize first, then validate.

Seeders and factories bypass Nova entirely, so seed digits-only values and let the model mutator/accessor handle presentation. Add a fake()->cpf() (via fakerphp/faker pt_BR locale) helper to keep fixtures valid.

API/Inertia consumers should receive raw digits and format client-side; do not leak the Nova field's mask into your JSON contracts.

Gotchas and Tips

  • Maintenance risk is the headline. 1 star / 0 dependents means no issue triage, no Nova 5 readiness, and possible dead links. Before committing, check: last commit date, composer.json Nova constraint, whether dist/js is committed (needed if you cannot npm run dev inside the package). If any of these fail, budget half a day to fork it into app/Nova/Fields or write a ~60-line field yourself — the Vue side is a single masked input.
  • Nova version compatibility is the most common breakage. Nova 4/5 register field assets differently and use laravel-nova build tooling. A package built for Nova 2 will not "just work." Confirm the nova constraint and the component's mix/vite build path.
  • Masked vs unmasked storage is the #1 bug source. Verify with a real form submission and a Tinker insert; the two paths often diverge. If they do, add a model mutator rather than patching the Vue component.
  • Empty strings vs null. Masked inputs frequently submit "" or "__.___.___-__" placeholders. Add 'nullable' and a prepareForValidation/middleware trim, or you will get not-null violations and phantom unique conflicts.
  • Alphanumeric CNPJ (2026). Brazil is moving CNPJ to an alphanumeric format; classic 14-digit numeric validation rules will reject future-issued CNPJs. Do not hardcode strlen === 14 && ctype_digit. Prefer a rule you control so you can update it in one place.
  • Debugging the field: if the mask does not appear, the compiled JS asset is not loading. Check nova:publish/vendor:publish for the field's dist, the browser console for 404s, and php artisan nova:asset. In Nova 4+, Nova::script()/Nova::style() registration must run from the service provider.
  • Extension points: subclass the field and override resolve/fill for storage normalization, or override the Vue component entirely (->component('my-cpf-field')). Forking is a legitimate strategy here — you gain the validation rule and the component, and you control the maintenance.
  • Do not use it for search/filter columns without normalization; WHERE cpf_cnpj LIKE '%123%' on masked data misses digit-only inputs.
  • Test the round-trip in a Pest/PHPUnit feature test hitting the Nova endpoint, not just the model — that is where mask/storage mismatches actually surface.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core