QR Code by Mohamad Muqiit Faturrahman
CommunityA powerful, modern and all in one QR code package designed exclusively for Filament v5.
Author:
Mohamad Muqiit Faturrahman
Package health
Automated checks of this plugin's Composer package
15 checks
- Failed: GitHub Actions pinned to SHA — View details on Plumb
- Skipped: GitLab CI includes pinned to SHA
- Passed: Open security advisories
- Passed: Dependabot PR responsiveness — No open Dependabot PRs.
- Skipped: Renovate MR responsiveness
- Failed: Dependabot or Renovate configured — No dependency updater configuration found. View details on Plumb
- Skipped: Dependency update cooldown configured
- Failed: Provides a security policy — View details on Plumb
- Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
- Passed: Commit and release recency — Active: last commit 0 days ago; last release 0 days ago.
-
Passed:
composer.lock not committed by library
—
composer.lockis absent from the released dist archive. - Warning: Dist archive is lean
-
Passed:
Current Laravel version supported
—
Package dependencies resolve together with current Laravel
13.0. -
Passed:
Current PHP version supported
—
Constraint
^8.2supports current PHP8.5. - Skipped: Current Symfony version supported
filament/
namespace. Review the source and install at your own risk. Found
malware or an unresolved security issue the author won't
address?
Report it
.
Documentation
- Requirements
- How it works
- Installation
- Quick start
- Usage
- Troubleshooting
- Reporting issues
- Contributing
- Changelog
- Security Vulnerabilities
- Credits
- License
A powerful, modern QR code package designed exclusively for Filament v5 and Laravel 11 / 12 / 13.
Features:
- 📷 Interactive Camera Scanner: Real-time camera stream, rear-camera prioritization with remembered choice, responsive decode box synced to the on-screen reticle, and image upload fallback with zero CDN latency.
- 🔗 Sequential Scanning: One shared camera feed walks through a multi-field checklist (
QrScanSequence), with editable or locked steps. - 🔫 Hardware Scanner Support: Native burst keystroke detection (<50ms) that absorbs trailing
Enterkeys to prevent premature form submissions. - 📦 Batch Collector (Repeaters & Lists): Continuous scanning mode with duplicate protection and sound/haptic confirmation for rapid inventory logging.
- 🎨 Full QR Generator Suite: Generate SVG & PNG QR codes with captions/text overlays, logo embedding, and schema components for Forms, Tables, Infolists, and Actions.
- 🔊 Sensory Confirmation: Instant zero-latency synthesized Web Audio tone and mobile haptic feedback, pitch and duration tunable per component.
#Requirements
- PHP
^8.2, Laravel 11/12/13, Filament v5. - PNG generation needs
gdorimagickplus system fonts (fonts-dejavu-coreon Debian). - Camera scanning needs a secure context (
httpsorlocalhost). - The camera bundle (
html5-qrcode) is compiled intoresources/dist/— no CDN. After changing anything underresources/jsorresources/css, rebuild withnpm run build(CI fails when committeddist/is stale).
#How it works
- Camera scanning runs fully in the browser: a modal viewfinder streams the camera through the bundled decoder. The decoder chunk lazy-loads on first camera use; pages that only render QR images never fetch it.
- Hardware scanners emulate keyboards: they burst keystrokes in a few dozen milliseconds and end with a terminator key (
Enter/Tab). The interceptor buffers bursts, swallows the terminator so forms don't submit, and routes the value to the active field. - Sequences and collectors write through
$wire.setinto your Livewire form state, so scanned values behave like typed input (validation and reactivity included). Camera DOM lives underwire:ignoreso Livewire morphs never kill a running feed. - Generation is server-side: renders are cached in-process plus in the Laravel cache, so repeated values encode once. Table modal previews load lazily through a signed image route instead of embedding a data-URI per row.
#Installation
You can install the package via composer:
composer require mmuqiitf/filament-qr-code
Publish the configuration file (optional):
php artisan vendor:publish --tag="filament-qr-code-config"
Register the plugin in your Filament Panel Provider (optional — JS/CSS
auto-register globally via the service provider, so existing installs that
already call ->plugin() keep working with no duplicate tags):
use Mmuqiitf\FilamentQrCode\FilamentQrCodePlugin;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugin(FilamentQrCodePlugin::make());
}
The camera decoder (html5-qrcode, ~375K) is split into a lazy chunk:
the global bundle is ~20K and the decoder downloads once, on first camera
use. Pages that only render QR images never fetch it.
#Symbologies
Pass BarcodeFormat cases (or raw strings) via ->formats([...]) on every camera component. Supported: QrCode, Aztec, DataMatrix, Maxicode, Codabar, Code39, Code93, Code128, Itf, Ean13, Ean8, UpcA, UpcE. Filtering formats speeds up decoding and cuts false positives — always set it when you know what you scan. One-dimensional codes automatically get a wide decode band instead of a square.
#Quick start
use Mmuqiitf\FilamentQrCode\Forms\Components\QrScanner;
QrScanner::make('sku')->label('SKU'),
Camera modal, upload fallback, and hardware-scanner capture all work out of the box. Add ->formats([...]) when you know the symbology — the guides below are upgrades to this.
#Usage
#Which component do I need?
| Job | Use | Why not the others |
|---|---|---|
| One input scanned by camera, upload, typing, or gun | QrScanner |
Sequence/collector add moving parts a single field doesn't need. |
| Cashier/POS gun, no camera UI | QrHardwareScannerListener + one funnel method |
QrScanner's field listener would double-handle the same burst. |
| One camera walking many fields in order | QrScanSequence |
Chained nextField() hops between separate cameras; the sequence shares one feed. |
| Two fields, hand focus from one to the next | QrScanner::nextField() |
A sequence is overkill without a shared checklist. |
| Many scans into one list (stocktake, receiving) | QrCollector / QrCollectAction |
Sequences map one scan to one field; collectors append. |
| Show a QR (form, table, infolist, download) | QrCodeDisplay / QrColumn / QrEntry / DownloadQrAction |
Scanner components capture; these only render. |
| Many QRs out at once (labels, handover) | DownloadQrBulkAction + print sheet |
Single downloads don't scale past a handful of rows. |
#Basic implementation
Single field with camera, upload fallback, and hardware-scanner capture:
use Mmuqiitf\FilamentQrCode\Forms\Components\QrScanner;
use Mmuqiitf\FilamentQrCode\Enums\BarcodeFormat;
QrScanner::make('sku')
->formats([BarcodeFormat::QrCode, BarcodeFormat::Code128])
->sound(true);
Hands-free station — one gun driving the whole page, no camera UI:
use Mmuqiitf\FilamentQrCode\Forms\Components\QrHardwareScannerListener;
QrHardwareScannerListener::make(['sku', 'quantity'])
->autoFocusNext(true);
One camera walking many fields in order:
use Mmuqiitf\FilamentQrCode\Forms\Components\QrScanSequence;
QrScanSequence::make(['batch_number', 'serial_number'])
->statePath('sequence')
->formats([BarcodeFormat::QrCode]);
Continuous batch scanning into a list:
use Mmuqiitf\FilamentQrCode\Forms\Components\QrCollector;
QrCollector::make('scanned_items')
->allowDuplicates(false);
Render a QR from record data:
use Mmuqiitf\FilamentQrCode\Forms\Components\QrCodeDisplay;
use Mmuqiitf\FilamentQrCode\Tables\Columns\QrColumn;
QrCodeDisplay::make('qr')
->data(fn ($record) => $record?->uuid)
->size(200);
QrColumn::make('sku')
->thumbnailSize(48)
->previewable();
Cashier/POS flow with a handheld gun: see the POS tutorial.
#Advanced implementation
Tune defaults globally (php artisan vendor:publish --tag="filament-qr-code-config" → config/qr-code.php), or per component — component options always win:
QrScanner::make('sku')
->fps(25)
->qrbox(250)
->hardwareScanner(terminators: ['Enter', 'Tab'], minBarcodeLength: 2)
->beepFrequency(880)
->beepDuration(80);
Normalize and reject live scans (scanFormat() / onScan() never run on live scans — they are programmatic-only):
QrScanner::make('sku')
->normalizeUsing(fn ($rawValue) => strtoupper(trim((string) $rawValue)))
->rejectWhen(fn ($state) => strlen((string) $state) < 3, 'Barcode too short.');
Audit server-observed scans (live scans stay client-side until they reach the server):
use Illuminate\Support\Facades\Event;
use Mmuqiitf\FilamentQrCode\Events\QrCodeScanned;
// config/qr-code.php
'audit' => ['enabled' => true, 'channel' => null],
// or listen yourself:
Event::listen(QrCodeScanned::class, fn ($event) => logger()->info("Scanned {$event->code}"));
Build payloads without hand-escaping:
use Mmuqiitf\FilamentQrCode\Support\QrPayload;
QrPayload::wifi('Shop Floor', 'secret-1');
UI strings live under filament-qr-code::ui (publish with --tag="filament-qr-code-translations"); wrap QR images in .filament-qr-label-sheet / .filament-qr-label for printable shelf labels. Full tables, events, and extension hooks: Reference.
#Full guides
- Scanning — camera field, station listener, sequences, focus handoff, POS tutorial.
- Batch collecting — continuous inventory scanning in repeaters and tables.
- Generating — display components, download actions, facade, payloads.
- Reference — configuration, events, customizing, extending.
#Troubleshooting
Run the built-in checks first:
php artisan qr-code:doctor
| Symptom | Likely cause | Fix |
|---|---|---|
| Camera modal says no devices / access denied | Page served over plain http (not localhost) |
Serve via https or test on localhost; browsers block cameras in insecure contexts. |
| Camera modal empty on first open | Permission not granted yet, labels unavailable | Grant permission, reopen; the remembered localStorage choice wins afterwards. |
| Stale scanner UI after updating the package | Committed dist/ rebuilt but host serving old assets |
npm run build in the package, then php artisan filament:assets in the host app. |
| PNG looks wrong / text overlay is blocky | Missing GD/Imagick or system fonts | Install gd or imagick plus fonts-dejavu-core; the service falls back to GD bitmap fonts otherwise. |
| Sequence submit misses scanned values | statePathPrefix() doesn't match the schema statePath() |
Set both to the same prefix, or give the sequence ->statePath() and read via mergeSequenceState(). A banner warns in the UI when they differ. |
| Same burst handled twice | Field QrScanner listener + page QrHardwareScannerListener both active |
Keep the global listener; field handlers stand down automatically (or ->suppressWhenGlobalListener(false)). |
| Typed text becomes a "scan" | minBarcodeLength too low for a keyboard-heavy form |
Raise minBarcodeLength to 4–6 on that component. |
| Table page is slow with many QRs | Eager modal data-URIs per row | Keep ->lazyModal() (default) and the persistent cache enabled; tune generator.cache_ttl. |
#Reporting issues
- Run
php artisan qr-code:doctorand include its output. - Include your PHP / Laravel / Filament versions (
php -v,composer show laravel/framework filament/filament), plus for camera issues the browser and whether the page is served overhttps/localhost, and for gun issues the scanner model and its suffix keys. - Describe expected vs actual, with a minimal schema snippet that reproduces it.
Security vulnerabilities are handled privately — see Security Vulnerabilities, not public issues.
#Contributing
PRs welcome! See CONTRIBUTING.md for the test suite, static analysis, code style, and frontend build workflow.
#Changelog
Please see CHANGELOG.md for more information on what has changed recently.
#Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
#Credits
#License
The MIT License (MIT). Please see License File for more information.
Featured Plugins
A selection of plugins curated by the Filament team
Soft Theme
A theme that gives panels a warm, approachable look with rounded shapes, gentle colors, and serif headings.
Filament
Advanced Tables (formerly Filter Sets)
Supercharge your tables with powerful features like user-customizable views, quick filters, multi-column sorting, advanced table searching, convenient view management, and more. Compatible with Resource Panel Tables, Relation Managers, Table Widgets, and Table Builder!
Kenneth Sese
Compact Theme
A theme that makes data-heavy panels easier to scan by fitting more useful information on each screen.
Filament