Skip to main content
WireKit
Copy for LLM

QR Code

The <x-wirekit::qr-code> component generates a QR code as inline SVG from any string value. It uses the bacon/bacon-qr-code PHP library for server-side generation — no JavaScript required.

Basic Usage

Basic QR Code

Custom Size

The size prop controls both width and height in pixels:

Different Sizes

Custom Colors

Use color for the foreground modules and background for the quiet zone. Both accept any CSS hex color:

Colored QR Codes
{{-- Blue on light blue --}}
<x-wirekit::qr-code value="..." color="#1e40af" background="#dbeafe" />

{{-- Inverted: white on dark --}}
<x-wirekit::qr-code value="..." color="#ffffff" background="#18181b" />

Error Correction Level

Higher error correction allows the QR code to remain scannable even when partially obscured (e.g. by a logo overlay). The trade-off is a denser pattern with more modules:

Error Correction Levels
L (7%)
M (15%)
Q (25%)
H (30%)

Use H (30% correction) when you plan to overlay a logo on the QR code.

Margin (Quiet Zone)

The margin prop controls the white border around the QR code in module units. The QR standard recommends at least 4 modules, but you can reduce it for tight layouts:

Margin (Quiet Zone)
margin=0
margin=2
margin=4

Complex Examples

WiFi Network

Encode WiFi credentials using the standard WiFi QR format. Scanning this QR connects the device automatically:

WiFi Network QR
GuestNetwork
Security: WPA/WPA2
Password: welcome2024
Scan to connect automatically

vCard Contact

Encode contact information as a vCard — scanning adds the contact to the phone's address book:

vCard Contact QR
Jane Smith
Acme Inc.
+1-555-123-4567
[email protected]
Scan to add contact

Branded with Logo Overlay

Use high error correction (H) so the QR remains scannable with a logo on top:

Branded with Logo Overlay

Keep the logo under ~30% of the QR area so the error correction can recover the obscured modules.

<div class="relative inline-block">
    <x-wirekit::qr-code
        value="https://wirekit.app"
        :size="250"
        errorCorrection="H"
    />
    <img
        src="/logo.svg"
        alt=""
        aria-hidden="true"
        class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-12 h-12 bg-white p-1 rounded"
    />
</div>

Dynamic Values

Use Blade expressions to encode dynamic content:

{{-- Route URL --}}
<x-wirekit::qr-code :value="route('invite', $token)" />

{{-- Email mailto --}}
<x-wirekit::qr-code :value="'mailto:' . $user->email" />

{{-- Coupon code --}}
<x-wirekit::qr-code :value="$couponCode" :size="150" />

SVG Output

The component always renders SVG — never a raster image. This means:

  • Infinitely scalable — looks sharp on any screen density (Retina, 4K)
  • Styleable — the SVG respects the color and background props
  • Printable — vector output at any resolution
  • Lightweight — typically 2–5 KB inline SVG, no external requests
  • Accessible — wrapped in role="img" with aria-label

The SVG is rendered inline in the DOM (not as <img src="...">) so it's part of the page's DOM tree and can be styled with CSS if needed.

Requirements

This component requires the bacon/bacon-qr-code PHP package:

composer require bacon/bacon-qr-code

The package is a suggested dependency of WireKit, not a required one. If the package is not installed, the component renders a styled placeholder instead of a QR code.

Fallback Behavior

When bacon/bacon-qr-code is not installed or the value is empty, the component renders a placeholder <div> with the text "QR Code" — styled with WireKit design tokens (muted background, border, rounded corners). This ensures the layout does not break.

Props

Prop Type Default Description
value string '' The text or URL to encode
size int 200 Width and height in pixels
color string '#000000' Foreground (module) color as hex
background string '#ffffff' Background color as hex
errorCorrection string 'L' Error correction level: L (7%), M (15%), Q (25%), H (30%)
margin int 4 Quiet zone width in QR modules
accessibleLabel string|null null Accessible name announced by screen readers. Defaults to "QR code" when omitted — pass a purpose-describing label like "Scan to install WireKit" rather than letting the encoded URL leak as the announcement.
scope string|null null Scoped personalization key

Accessibility

  • Container: role="img" — identifies the element as an image to assistive technology
  • aria-label="QR code for {value}" — provides a descriptive accessible name including the encoded content
  • The QR code is purely visual — screen readers announce the label instead of attempting to parse the SVG paths

If the encoded value contains sensitive data (like API keys), consider overriding the aria-label to avoid exposing it to screen readers: aria-label="QR code for your API key".

Keyboard Interaction

This component is purely presentational and does not respond to keyboard input.

Pitfalls

  • Don't QR-encode personally identifiable data. QR codes are public — anyone within camera range can capture them. Encode opaque tokens and resolve server-side.

Design Tokens

The rendered QR code itself is a black-on-transparent SVG (the bacon/bacon-qr-code package emits paths in currentColor-equivalent black for maximum scanner contrast). Token usage is concentrated on the placeholder fallback and the surrounding container:

Token Used for
--text-wk-sm Placeholder label font size
--color-wk-text-muted Placeholder label text
--color-wk-bg-muted Placeholder background
--color-wk-border Placeholder border
--border-wk-width Placeholder border width
--radius-wk-md Placeholder border radius

Personalization

Override classes globally via WireKit::personalize():

use Pushery\WireKit\WireKit;

WireKit::personalize('qr-code', [
    'base' => 'inline-block p-4 bg-white rounded-lg shadow',
]);

Further Reading

Was this page helpful?

Thanks — that helps.

Voting requires cookies or local storage. What we store