QR Code
betaA real, scannable QR code made on the device, as ink on a white tile in both themes, with its quiet zone built in.
Preview
pass
Ava Clarke
Demo day guest
Or check in by name, or with the code 7Q2K.
size
level
margin
poster
too long
Install
1. Add the registry to
components.json, once per app. Without it, the shadcn CLI looks up@txbrendanin a public list that txbrendan/ui does not control.npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.
npx shadcn@latest add @txbrendan/theme3. Add the component.
npx shadcn@latest add @txbrendan/qr-code
Use it for
- A code people scan with a phone: a check-in, a join link, an event pass, a printed poster.
- Pass value, usually a link, and aria-label, like 'Check-in code for the Workshop'.
- Always pair it with another way in, like a short code to type or check-in by name. Nothing should be camera-only.
- Pass className='w-full' for a poster. It scales as vector.
- Use encodeQRCode(value) for the modules alone, to draw them some other way.
Avoid it for
- A link people can click on the same screen. Show the link.
- Long text, like a whole message. A long value makes a dense code that is hard to scan. Link to the text instead.
- Secrets. Anyone who can see the code can read it.
Props
- value
Required. What the code holds, usually a link. It is encoded as UTF-8 bytes.
string
- aria-label
Required. Names the code for screen readers, like 'Ava Clarke's guest pass'.
string
- size
The most it draws: 120, 160, or 240px. Modules snap to whole pixels, so edges stay crisp.
"sm" | "md" | "lg" · default "md"
- level
The least error correction. It rises for free while the data still fits the same size.
"L" | "M" | "Q" | "H" · default "M"
- margin
The white quiet zone around the code, in modules. 4 is the standard's minimum.
number · default 4
- className
Extra classes. Later classes win, so className='w-full max-w-none' fills a poster.
string
| Prop | Type | Default | What it does |
|---|---|---|---|
| value | string | - | Required. What the code holds, usually a link. It is encoded as UTF-8 bytes. |
| aria-label | string | - | Required. Names the code for screen readers, like 'Ava Clarke's guest pass'. |
| size | "sm" | "md" | "lg" | "md" | The most it draws: 120, 160, or 240px. Modules snap to whole pixels, so edges stay crisp. |
| level | "L" | "M" | "Q" | "H" | "M" | The least error correction. It rises for free while the data still fits the same size. |
| margin | number | 4 | The white quiet zone around the code, in modules. 4 is the standard's minimum. |
| className | string | - | Extra classes. Later classes win, so className='w-full max-w-none' fills a poster. |
Accessibility
- Renders an <svg> with role="img", named by aria-label. TypeScript requires it.
- The code is ink on a white tile in light and dark, since many phone cameras cannot read a light code on dark.
- A value too long for any code shows an empty dashed tile, and its name says so.
- Screen readers cannot read the code itself. Put the link or a short code beside it as text.
Examples
A pass, named for screen readers
<QRCode value="https://example.com/p/ava-clarke-7q2k" aria-label="Ava Clarke's guest pass" />With another way in
<div className="flex items-center gap-4">
<QRCode value="https://example.com/check-in/4821" aria-label="Check-in code for the Workshop" size="sm" />
<p>Or type the code 4821 at the door.</p>
</div>For a poster
<QRCode value="https://example.com/join" aria-label="Join the team" level="H" className="w-full max-w-none" />