In this article, I'll walk you through creating a QR scanner in Next.js using the @yudiel/react-qr-scanner
library. We'll integrate it with basic functionalities like selecting devices, pausing scans, and customizing tracker overlays.
Why Use @yudiel/react-qr-scanner?
The @yudiel/react-qr-scanner
library provides an easy-to-use interface for scanning various barcode and QR code formats. It supports custom overlays and multiple formats, making it versatile for different applications.
Prerequisites
- Familiarity with React and Next.js.
- A Next.js project setup.
- Install the library:
yarn add @yudiel/react-qr-scanner
- for local testing scanner you need to enabled below chrome flag:
chrome://flags/#usafely-treat-insecure-origin-as-secure
Note: go to chrome tab and then search usafely-treat-insecure-origin-as-secure and enabled.
Implementation
Here’s the complete code for the scanner page in Next.js.
ScannerPage Component
"use client"; import { useState } from "react"; import { Scanner, useDevices, outline, boundingBox, centerText, } from "@yudiel/react-qr-scanner"; const styles = { container: { width: 400, margin: "auto", }, controls: { marginBottom: 8, }, }; export default function ScannerPage() { const [deviceId, setDeviceId] = useState<string | undefined>(undefined); const [tracker, setTracker] = useState<string | undefined>("centerText"); const [pause, setPause] = useState(false); const devices = useDevices(); function getTracker() { switch (tracker) { case "outline": return outline; case "boundingBox": return boundingBox; case "centerText": return centerText; default: return undefined; } } const handleScan = async (data: string) => { setPause(true); try { const response = await fetch( `your-api-url?code=${encodeURIComponent(data)}` ); const result = await response.json(); if (response.ok && result.success) { alert("Success! Welcome to the conference."); } else { alert(result.message); } } catch (error: unknown) { console.log(error); } finally { setPause(false); } }; return ( <div> <div style={styles.controls}> <select onChange={(e) => setDeviceId(e.target.value)}> <option value={undefined}>Select a device</option> {devices.map((device, index) => ( <option key={index} value={device.deviceId}> {device.label} </option> ))} </select> <select style={{ marginLeft: 5 }} onChange={(e) => setTracker(e.target.value)} > <option value="centerText">Center Text</option> <option value="outline">Outline</option> <option value="boundingBox">Bounding Box</option> <option value={undefined}>No Tracker</option> </select> </div> <Scanner formats={[ "qr_code", "micro_qr_code", "rm_qr_code", "maxi_code", "pdf417", "aztec", "data_matrix", "matrix_codes", "dx_film_edge", "databar", "databar_expanded", "codabar", "code_39", "code_93", "code_128", "ean_8", "ean_13", "itf", "linear_codes", "upc_a", "upc_e", ]} constraints={{ deviceId: deviceId, }} onScan={(detectedCodes) => { handleScan(detectedCodes[0].rawValue); }} onError={(error) => { console.log(`onError: ${error}'`); }} styles={{ container: { height: "400px", width: "350px" } }} components={{ audio: true, onOff: true, torch: true, zoom: true, finder: true, tracker: getTracker(), }} allowMultiple={true} scanDelay={2000} paused={pause} /> </div> ); }
Code Explanation
Device Selection: Use useDevices to fetch the list of available video input devices.
Custom Tracker: Provide visual guidance for users with overlays like outline, boundingBox, and centerText.
Scan Handling: Pause the scanner after detecting a QR code, and fetch API data for validation.
Scanner Configuration: Customize scanner formats, overlays, and multiple QR codes handling.
Top comments (0)