The code updates as you type.
import * as React from "react"
import { Field, FieldControl, FieldDescription, FieldLabel } from "@hel/ui/field"When to use it#
Use a QR code to move something from one screen to another: an invite link to scan from a phone, the Wi-Fi details at a cafe, a ticket, a contact on a business card. It is drawn as one SVG, so it stays sharp at any size and does not mirror in right-to-left pages.
Do not use it for something people can just click. A QR code is for the person who is looking at one screen and holding another device.
Import#
import {
QrCode,
qrPayload,
qrCodeToSvg,
qrCodeToBlob,
downloadQrCode,
copyQrCode,
} from "@hel/ui/qr-code"Usage#
<QrCode value="https://example.com/invite/4821" size={160} label="Invite link" />Nothing is drawn while value is empty, or when it is too long for any code. Pass onEncodeError to know about the second case. Give the code a label that says what it opens, because a screen reader cannot read the picture.
The code is black on white by default, and it does not follow the theme. That is on purpose: scanners expect a dark code on a light background, and a code in light colors on a dark page often cannot be read.
Examples#
Shapes and colors#
moduleShape changes the small squares, eyeShape the three big squares in the corners, and color, eyeColor and eyeBallColor their colors. background can be any color or "transparent", and radius rounds its corners. Keep the code dark against its background, and test a styled code with a real phone before you print it.
Square
Rounded
Dots
Classy
Navy
Soft
import { Flex } from "@hel/ui/flex"
import { QrCode } from "@hel/ui/qr-code"
import type { QrCodeProps } from "@hel/ui/qr-code"moduleShape is one of square, rounded, dots, classy, soft, diamond, cross, vertical-bars and horizontal-bars. eyeShape is square, rounded or circle.
A logo in the middle#
logo puts an image in the center and leaves out the squares under it. It can take up to a quarter of the width, and the default is 0.2. A code with a logo always uses the highest error correction, because the logo hides part of the data, so the code gets denser. A smaller logo and a shorter value scan more reliably.
import { QrCode } from "@hel/ui/qr-code"
export function QrCodeLogo() {Wi-Fi, email, contacts and downloads#
A QR code says text, and scanners treat some text as an action. qrPayload builds that text for you: wifi, email, phone, sms, whatsapp, geo and vcard. Pass the result as the value.
To save a code, use downloadQrCode with png, jpeg, webp or svg. It makes the picture at least as large as size and keeps the edges sharp. copyQrCode puts a PNG on the clipboard, which needs a secure page, and qrCodeToSvg gives you the text of an SVG file, even on a server.
Scanning joins the network.
import * as React from "react"
import { Download } from "lucide-react"
Props#
QrCode#
| Prop | Type | Default |
|---|---|---|
value | string | required |
size | number (pixels) | 160 |
color | a CSS color | "#000000" |
background | a CSS color | "#ffffff" |
moduleShape | see above | "square" |
eyeShape | "square" | "rounded" | "circle" | "square" |
eyeColor | a CSS color | same as color |
eyeBallColor | a CSS color | same as eyeColor |
level | "L" | "M" | "Q" | "H" | "M" |
quietZone | number (modules) | 4 |
radius | number (pixels) | 0 |
logo | { src: string, size?: number } | none |
label | string | "QR code" |
onEncodeError | (error: Error) => void | none |
level is how much damage the code can take and still scan. A higher level makes a denser code. Scanners need a quiet zone of at least 4 modules, so only make it smaller if you are sure.
Functions#
| Function | Use |
|---|---|
downloadQrCode(options, { filename, format, size }) | Saves the code as a file. |
copyQrCode(options, { size }) | Copies the code as a PNG picture. |
qrCodeToBlob(options, { format, size, quality }) | The code as a Blob. |
qrCodeToSvg(options) | The code as the text of an SVG file. |
options is the same object you would give the component, such as { value, color, moduleShape }.