Looking to hire Laravel developers? Try LaraJobs

laravel-qrcode maintained by abduns

Description
Laravel 12/13 bridge for abduns/qrcode: Facade, Blade, response()->qrcode(), and JSON/data-URI helpers for React, Vue, and Inertia.
Author
Last update
2026/08/27 04:21 (dev-main)
License
Links
Downloads
173
Tags

Comments
comments powered by Disqus

laravel-qrcode

Laravel 12/13 bridge for the abduns/qrcode generator. Server-side QR codes that drop into Blade, Inertia, React, Vue, or any JSON API.

CI Version Downloads License


Installation

composer require abduns/laravel-qrcode
php artisan vendor:publish --tag=qrcode-config

Requires PHP 8.2+ and Laravel 12 or 13. PNG output needs ext-gd. CI runs Pest, PHPStan, and php-cs-fixer on PHP 8.2–8.4 × Laravel 12 and PHP 8.3–8.4 × Laravel 13.


Quick Start

use Dunn\QrCode\Laravel\Facades\QrCode;

$svg     = QrCode::svg('https://example.com');     // SVG markup
$png     = QrCode::png('https://example.com');     // raw PNG bytes (ext-gd)
$uri     = QrCode::dataUri('https://example.com'); // data:image/svg+xml;base64,...
$payload = QrCode::payload('https://example.com'); // JSON-ready { mimeType, dataUri, svg }

For JavaScript frontends, start with payload() or dataUri(). Do not put png() bytes into JSON.


Usage with React, Vue, and Inertia

QR codes are generated in PHP. The browser only displays the result. Three patterns cover every Laravel + JS stack.

1. JSON payload (Inertia, SPA, API)

use Dunn\QrCode\Laravel\Facades\QrCode;

// API controller — returns JSON automatically
return QrCode::payload('https://example.com');

// Inertia
return Inertia::render('Ticket/Show', [
    'qr' => QrCode::payload($ticket->url),
]);

JSON body:

{
  "mimeType": "image/svg+xml",
  "dataUri": "data:image/svg+xml;base64,PHN2Zy...",
  "svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" ...></svg>"
}

React (Inertia)<img src> is the safe default:

export default function Ticket({ qr }) {
  return <img src={qr.dataUri} alt="QR code" width={300} height={300} />;
}

Inline SVG (only if you want to style the markup):

<div dangerouslySetInnerHTML={{ __html: qr.svg ?? '' }} />

Vue (Inertia):

<template>
  <img :src="qr.dataUri" alt="QR code" width="300" height="300" />
</template>

<script setup>
defineProps({
  qr: { type: Object, required: true },
})
</script>

Inline SVG:

<div v-html="qr.svg" />

SPA fetch:

const qr = await (await fetch('/api/qr')).json()
document.querySelector('#qr').src = qr.dataUri

2. Image URL (<img src="/qr/...">)

Works with React, Vue, Blade, mobile WebViews — anything that can load an image.

Route::get('/qr/{data}', function (string $data) {
    return response()->qrcode($data, maxAge: 86400);
});
<img src={`/qr/${encodeURIComponent(url)}`} alt="QR code" />
<img :src="`/qr/${encodeURIComponent(url)}`" alt="QR code" />

Content-Type follows the renderer (image/svg+xml by default, or image/png if you pin PNG). Every response includes an ETag.

3. Data URI only

When you already have a string prop and do not want the full payload:

return Inertia::render('Ticket/Show', [
    'qrSrc' => QrCode::dataUri($ticket->url),
]);
<img src={qrSrc} alt="QR code" />

PNG data URI (requires ext-gd):

use Dunn\QrCode\Renderer\Png\GdPngRenderer;

QrCode::dataUri('https://example.com', new GdPngRenderer());
// data:image/png;base64,iVBOR...

Blade

@qrcode('https://example.com')

The directive emits inline SVG. Keep config('qrcode.renderer') as svg if you use it — PNG bytes inline in HTML are not useful.


Response macro

// Image response (SVG by default)
Route::get('/qr/{data}', fn (string $data) => response()->qrcode($data));

// Cached for CDNs / <img src>
response()->qrcode($url, maxAge: 86400);

// Suggest a filename (inline — still works as <img src>)
response()->qrcode($url, filename: 'ticket.svg');

// Force a download
response()->qrcode($url, download: true, filename: 'ticket');

// PNG, styled, or a custom status
use Dunn\QrCode\Renderer\Png\GdPngRenderer;

response()->qrcode($url, 200, new GdPngRenderer(), filename: 'ticket.png');

Named arguments: filename, maxAge (seconds), download. A filename without an extension gets .svg / .png / .txt from the renderer MIME type.


Payloads (vCard, Wi-Fi, …)

use Dunn\QrCode\Laravel\Facades\QrCode;
use Dunn\QrCode\Payload\VCard;
use Dunn\QrCode\Payload\WifiAuth;

QrCode::url('https://example.com')->build();
QrCode::wifi('Office', 'hunter2', WifiAuth::WPA)->build();

$card = VCard::make('Jane Doe')
    ->withOrg('Acme')
    ->addEmail('jane@acme.com');

return QrCode::payload($card); // same JSON shape, any Stringable payload

Typed factories: url, text, phone, sms, email, geo, wifi, vCard, event. Each returns a core Builder with the configured ECC applied.


Styled output

use Dunn\QrCode\Laravel\Facades\QrCode;
use Dunn\QrCode\Renderer\Svg\SvgRenderer;
use Dunn\QrCode\Style\ModuleShape\RoundedModule;
use Dunn\QrCode\Style\Gradient\LinearGradient;
use Dunn\QrCode\Style\Gradient\GradientStop;
use Dunn\QrCode\Style\Color;

$renderer = new SvgRenderer(
    moduleShape: new RoundedModule(),
    dotColor: new LinearGradient([
        new GradientStop(0.0, Color::hex('#264653')),
        new GradientStop(1.0, Color::hex('#2a9d8f')),
    ]),
);

QrCode::payload('https://example.com', $renderer);
QrCode::withRenderer($renderer)->dataUri('https://example.com');

Configuration

config/qrcode.php:

[
    'ecc'        => EccLevel::Medium,
    'renderer'   => 'svg',         // 'svg' | 'png' | 'console'
    'size'       => 300,
    'margin'     => 4,
    'foreground' => '#000000',
    'background' => '#ffffff',
]

renderer drives render(), payload(), dataUri(), toArray(), and response()->qrcode(). It does not change @qrcode (SVG-only by intent) or svg() / png() / console() (those force a family). size / margin / colours are ignored once you pass a custom renderer.


Error handling

The bridge does not swallow core exceptions. Catch around payload(), response()->qrcode(), and the Blade directive:

  • Dunn\QrCode\Exception\DataTooLongException — payload exceeds the chosen ECC/version
  • Dunn\QrCode\Exception\InvalidConfigurationException — renderer/config errors
  • Dunn\QrCode\Exception\PayloadException — invalid vCard / Wi-Fi / URL / … value

Testing

composer test

Compatibility

Platform Supported
PHP 8.2 / 8.3 / 8.4 ✅ CI
Laravel 12 ✅ CI (PHP 8.2–8.4, Pest 3)
Laravel 13 ✅ CI (PHP 8.3–8.4, Pest 4; Laravel 13 needs PHP 8.3+)
Inertia + React / Vue ✅ (payload() / dataUri())
JSON API / SPA ✅ (return QrCode::payload(...))
Blade ✅ (@qrcode)

License

MIT