QR Code
A QR code for a link, drawn as one crisp SVG — dark modules on a light rounded tile in both themes, with the standard quiet zone.
- Status
- Since
0.25.86- Accessibility pattern
- an image named by what scanning it does
Last updated
Install
Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for QR Code before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify qr-codeInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/qr-codeRun the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.
It also adds the sanctioned engine to your package.json: uqr (QR encoder (pure; renders nothing)).
Usage
import { QrCode } from "@/components/ui/qr-code";
<QrCode value={recordUrl} label="Open this meeting on your phone" />;QrCode hands a link to a phone. It encodes value during render — on the server or the client,
with no effect and no canvas — and draws the matrix as a single SVG path, so it stays sharp at any
size. The tile is light and the modules dark in both themes, because many scanners cannot read a
code drawn light-on-dark; the standard 4-module quiet zone is part of the drawing, so it needs no
padding around it.
Examples
Sizes
The default is size-40 (160px). Pass any size-* class; the code scales with its box. Keep a
code you expect to be scanned from a laptop screen at 160px or more.
Error correction
errorCorrection trades density for robustness: L survives 7% damage, M (the default) 15%,
Q 25% and H 30%. A higher level draws more, smaller modules for the same value — use M for a
link on a screen, and Q or H only when the code may be printed and worn.
Empty
An empty value, or one too long for any QR version at the chosen level, never throws: it draws
the empty tile (data-state="invalid") at the same size and keeps its name. Show why next to it.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
label* | string | — | The accessible name: what scanning the code does ("Open this meeting on your phone"). The encoded value is not read out, so say where it leads. |
value* | string | — | The text the code carries — usually a URL. An empty value, or one too long for any QR
version at the chosen errorCorrection, draws the empty tile instead of throwing. |
errorCorrection | QrCodeErrorCorrection | "M" | How much of the code can be lost and still scan: L 7%, M 15%, Q 25%, H 30%. A higher
level draws more, smaller modules for the same value. |
quietZone | number | 4 | The light margin around the code, in modules. The QR standard asks for 4; scanners struggle below 2. |
Data attributes and CSS variables on QrCode
| Attribute | Values |
|---|---|
data-error-correction | mirrors a prop or state value |
data-slot | "qr-code" | "qr-code-modules" |
data-state | "invalid" | "ready" |
QrCode also takes the SVG element's own props (className, ref, id, style, …); the root is
the <svg>.
Accessibility
- The root is
role="img", named bylabel. Say what scanning does — "Open this meeting on your phone" — not "QR code": the encoded value is not read out. - A QR code is never the only way in. Show the link beside it, or a
CopyButtonfor it, so someone without a camera — or using a screen reader — can follow it. - Nothing in it is focusable or interactive.
| Contract | States tested |
|---|---|
| Behaviour | ready, invalid |
| Accessibility | labeled, browser-accessibility-test |
| Visual | default, invalid |