QR Code
A QR (Quick Response) Code is used to provide information or link which can be accessed by scanning the code with an app or a smartphone.
Good to know: The QR code encoding logic is built on top of the
uqr
library.
Features
- Renders an SVG element (good for SSR)
- Customize the size of the QR code in pixels
- Set the error correction level
- Customize the background and foreground color
Installation
To use the QR code machine in your project, run the following command in your command line:
npm install @zag-js/qr-code @zag-js/react # or yarn add @zag-js/qr-code @zag-js/react
npm install @zag-js/qr-code @zag-js/solid # or yarn add @zag-js/qr-code @zag-js/solid
npm install @zag-js/qr-code @zag-js/vue # or yarn add @zag-js/qr-code @zag-js/vue
npm install @zag-js/qr-code @zag-js/svelte # or yarn add @zag-js/qr-code @zag-js/svelte
This command will install the framework agnostic QR code logic and the reactive utilities for your framework of choice.
Anatomy
To set up the QR code correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Usage
First, import the QR code package into your project
import * as qrCode from "@zag-js/qr-code"
The QR code package exports two key functions:
machine
— The state machine logic for the QR code widget.connect
— The function that translates the machine's state to JSX attributes and event handlers.
Next, import the required hooks and functions for your framework and use the QR code machine in your project 🔥
import * as qrCode from "@zag-js/qr-code" import { useMachine, normalizeProps } from "@zag-js/react" import { useId } from "react" export function QRCode() { const [state, send] = useMachine( qrCode.machine({ id: useId(), value: "https://github.com/chakra-ui", }), ) const api = qrCode.connect(state, send, normalizeProps) return ( <div {...api.getRootProps()}> <svg {...api.getFrameProps()}> <path {...api.getPatternProps()} /> </svg> <div {...api.getOverlayProps()}> <img src="https://avatars.githubusercontent.com/u/54212428?s=88&v=4" alt="" /> </div> </div> ) }
import * as qrCode from "@zag-js/qr-code" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId } from "solid-js" export function QRCode() { const [state, send] = useMachine( qrCode.machine({ id: createUniqueId(), value: "https://github.com/chakra-ui", }), ) const api = createMemo(() => qrCode.connect(state, send, normalizeProps)) return ( <div {...api().getRootProps()}> <svg {...api().getFrameProps()}> <path {...api().getPatternProps()} /> </svg> <div {...api().getOverlayProps()}> <img src="https://avatars.githubusercontent.com/u/54212428?s=88&v=4" alt="" /> </div> </div> ) }
<script setup lang="ts"> import * as qrCode from "@zag-js/qr-code" import { normalizeProps, useMachine } from "@zag-js/vue" const controls = useControls(qrCodeControls) const [state, send] = useMachine( qrCode.machine({ id: "1", value: "https://github.com/chakra-ui", }), ) const api = computed(() => qrCode.connect(state.value, send, normalizeProps)) </script> <template> <div v-bind="api.getRootProps()"> <svg v-bind="api.getFrameProps()"> <path v-bind="api.getPatternProps()" /> </svg> <div v-bind="api.getOverlayProps()"> <img src="https://avatars.githubusercontent.com/u/54212428?s=88&v=4" alt="" /> </div> </div> </template>
<script lang="ts"> import * as qrCode from "@zag-js/qr-code" import { useMachine, normalizeProps } from "@zag-js/svelte" const [snapshot, send] = useMachine(qrCode.machine({ id: "1", value: "https://github.com/chakra-ui", })) const api = $derived(accordion.connect(snapshot, send, normalizeProps)) </script> <div {...api.getRootProps()}> <svg {...api.getFrameProps()}> <path {...api.getPatternProps()}></span> </svg> <div {...api.getOverlayProps()}> <img src="https://avatars.githubusercontent.com/u/54212428?s=88&v=4" alt="" /> </div> </div>
Setting the QR Code value
To set the value of the QR code, pass the value
property to the machine.
const [state, send] = useMachine( qrCode.machine({ // ... value: "https://example.com", }), )
Setting the correction level
Error correction allows for the QR code to be blocked or resized while still recoganizable. In some cases where the link is too long or the logo overlay covers a significant area, the error correction level can be increased.
The QR code machine accepts the following error correction levels:
L
: Allows recovery of up to 7% data loss (default)M
: Allows recovery of up to 15% data lossQ
: Allows recovery of up to 25% data lossH
: Allows recovery of up to 30% data loss
To set the error correction level, pass the encoding.ecc
or
encoding.boostEcc
context property.
const [state, send] = useMachine( qrCode.machine({ value: "...", encoding: { ecc: "H" }, }), )
The alternative is to enlarge the QRCode by increasing the size of the
svg
element.
Adding an overlay logo
To add a logo overlay to the QR code, render the image part. The logo will be automatically centered within the QR code.
<div {...api.getRootProps()}> <svg {...api.getFrameProps()}>{/** ... */}</svg> <div {...api.getOverlayProps()}> <img src="..." alt="" /> </div> </div>
Changing the color
To change the color of the QR code, set the fill
attribute on the path
part.
[data-scope="qr-code"][data-part="pattern"] { fill: green; }
To change the background color of the QR code, set the background-color
[data-scope="qr-code"][data-part="frame"] { background-color: white; }
Exporting the QR code
To export the QR code as an image, you can use the api.getDataURL
method.
api.getDataURL({ type: "image/png" }).then((url) => { // do something with the URL (like download it) })
Styling guide
Earlier, we mentioned that each QR code part has a data-part
attribute added
to them to select and style them in the DOM.
[data-scope="qr-code"][data-part="root"] { /* Styles for the root part */ } [data-scope="qr-code"][data-part="frame"] { /* Styles for the svg part */ } [data-scope="qr-code"][data-part="pattern"] { /* Styles for the path */ } [data-scope="qr-code"][data-part="overlay"] { /* Styles for the logo */ }
Methods and Properties
Machine Context
The QR code machine exposes the following context properties:
value
string
The value to encode.ids
Partial<{ root: string; frame: string; }>
The element ids.encoding
QrCodeGenerateOptions
The qr code encoding options.dir
"ltr" | "rtl"
The document's text/writing direction.id
string
The unique identifier of the machine.getRootNode
() => ShadowRoot | Node | Document
A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.
Machine API
The QR code api
exposes the following methods:
value
string
The value to encode.setValue
(value: string) => void
Set the value to encode.getDataUrl
(type: DataUrlType, quality?: number) => Promise<string>
Returns the data URL of the qr code.
Edit this page on GitHub