QR Code

A QR code for a link or a piece of text, drawn as sharp as you need it and ready to download.

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

PropTypeDefault
valuestringrequired
sizenumber (pixels)160
colora CSS color"#000000"
backgrounda CSS color"#ffffff"
moduleShapesee above"square"
eyeShape"square" | "rounded" | "circle""square"
eyeColora CSS colorsame as color
eyeBallColora CSS colorsame as eyeColor
level"L" | "M" | "Q" | "H""M"
quietZonenumber (modules)4
radiusnumber (pixels)0
logo{ src: string, size?: number }none
labelstring"QR code"
onEncodeError(error: Error) => voidnone

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

FunctionUse
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 }.