designthebox/barcode-field
A Laravel Nova field that renders barcodes directly in your admin panel. Display scannable codes for products, orders, or inventory records without extra tooling—add the field to your resource and let Nova handle the rest.
This is a small, single-maintainer package (24 stars, zero dependents, last release October 2024), so the first step is due diligence, not installation.
composer show -a designthebox/barcode-field and read the package's own composer.json to confirm the Laravel/Nova constraints it supports. With zero dependents, assume nothing about compatibility with your framework version.^:
composer require "designthebox/barcode-field:1.0.*"
src/ first. The package name implies a Nova-style custom field. Look for:
src/BarcodeField.php (or similarly named class extending Laravel\Nova\Fields\Field)src/BarcodeFieldServiceProvider.php — check whether it auto-registers assets via Nova::serving() or expects manual registration.resources/js/ — the Vue component that actually renders the input; this is where scanner behavior lives.php artisan vendor:publish --provider="DesignTheBox\BarcodeField\BarcodeFieldServiceProvider"
If the service provider has no publishes() call, the field likely ships pre-compiled JS in dist/ — verify the path exists.use DesignTheBox\BarcodeField\BarcodeField;
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
Text::make('Name'),
BarcodeField::make('Barcode')
->rules('required', 'string', 'max:64')
->help('Scan with a handheld reader or type manually'),
];
}
Keyboard-wedge scanners as the primary input. Almost all hardware barcode scanners emulate a keyboard: they type the digits and suffix with Enter. Build around that:
Enter/Tab rather than requiring a click.Separate "value" from "image." Store the barcode string in the database; render the image on demand. A clean split:
// Model
protected static function booted()
{
static::saving(function ($model) {
if (blank($model->barcode)) {
$model->barcode = static::generateUniqueBarcode();
}
});
}
Use picqer/php-barcode-generator or milon/barcode for SVG/PNG output in detail views:
public function barcodeSvg(): string
{
return (new Picqer\Barcode\Types\TypeCode128())
->getBarcode($this->barcode, new Picqer\Barcode\Renderers\SvgRenderer())
->getBarcode();
}
Lookup / scan-to-find workflow. The most valuable day-to-day use is "scan a box, open the record." Implement it as a route + Nova filter or a dedicated search page:
Route::get('/scan/{barcode}', fn (string $barcode) =>
redirect()->route('nova.resources.detail', [
'resource' => 'items', 'resourceId' => Item::where('barcode', $barcode)->value('id'),
])
);
Keep the barcode column indexed (ideally unique per tenant, not globally).
Nova integration tips.
->searchable() if the field should feed Nova's global search — pair with a DB index.->displayUsing(fn ($value) => $value) if you want the raw string in the index but a rendered image on the detail page.->component('custom-barcode') after publishing JS to customize scanner behavior without forking.php artisan barcodes:generate --missing --chunk=500
Validation and uniqueness.
unique constraint and a Rule::unique validation rule — client-side checks are advisory only.do { $value = 'BC-' . strtoupper(Str::random(10)); }
while (static::where('barcode', $value)->exists());
trim, strip newlines/CR, uppercase) because scanner suffixes vary by firmware.field.js or the Vue component. Fixes: re-register in NovaServiceProvider::boot() with Nova::script('barcode-field', __DIR__.'/../dist/js/field.js'), clear nova-components caches, or run php artisan nova:publish.mix-manifest.json); newer ones use Vite. If the manifest is stale or missing, rebuild locally:
npm install && npm run production
(or npm run build for Vite). Expect this if the package was built for a different Node version.Tab, some prefix with a Shift keyevent. Strip whitespace and control characters before validating. If you get truncation, check whether the field's maxlength or regex is rejecting the suffix.creating hook without a uniqueness constraint. Always back it with a DB unique index and catch QueryException, then retry.php artisan nova:check (Nova 4+) for asset-registration errors, and check storage/logs/laravel.log for exceptions thrown within Nova::serving. If the field silently ignores values, dump the request payload — some custom fields send a nested object ({ value: "..." }) rather than a string, which breaks naive validation rules.How can I help you explore Laravel packages today?