QR code generation isn't something to hand-roll — simplesoftwareio/simple-qrcode (a Laravel-friendly wrapper around the widely used endroid/qr-code library) is the standard, well-maintained choice, and covers everything from a plain PNG to a downloadable SVG with a logo embedded in the center.
1. Installation
composer require simplesoftwareio/simple-qrcode
2. Generating a basic QR code
use SimpleSoftwareIO\QrCode\Facades\QrCode;
// In a Blade view, rendered directly as inline SVG:
{!! QrCode::size(200)->generate('https://readerstacks.com') !!}
By default this generates an SVG, embedded directly in the HTML — no separate image file or route is needed for a QR code that's just being displayed on a page.
3. Returning it as a downloadable image response
use SimpleSoftwareIO\QrCode\Facades\QrCode;
Route::get('/qrcode/{text}', function (string $text) {
return response(QrCode::format('png')->size(300)->generate($text))
->header('Content-Type', 'image/png');
});
4. Error correction level
QrCode::errorCorrection('H')->generate('https://readerstacks.com');
QR codes include built-in redundancy so they still scan correctly even partially damaged or obscured — the error-correction level (L, M, Q, H, from roughly 7% to 30% recoverable data) controls how much redundancy is built in. Higher levels tolerate more damage or an embedded logo covering part of the code, at the cost of a visually denser pattern; H is the standard choice specifically when a logo will be embedded in the center.
5. Embedding a logo
QrCode::size(300)
->errorCorrection('H')
->merge('/path/to/logo.png', 0.2, true)
->generate('https://readerstacks.com');
The second argument to merge() (0.2 here) is the logo's size as a fraction of the QR code's total size — keeping it around 20–25% and pairing it with high (H) error correction is what keeps the code scannable despite the logo covering part of the pattern; a larger logo or lower error correction risks producing a code that fails to scan reliably.
6. What to actually encode
A QR code pointing at a URL that might change later (a specific product page, a time-limited offer) is more resilient if it points at a stable redirect URL the app controls, rather than the final destination directly — that way the destination can be updated later without needing to reprint or redistribute the QR code itself.