useHooks.iov4.1.2
DocsBlogGitHub
Hooks
No hooks found in any category.

useBarcodeDetector

sensors

Installation

npx usehooks-cli@latest add use-barcode-detector

Description

A hook for detecting barcodes in images using the Web Barcode Detection API. Supports various barcode formats including QR codes, Code 128, EAN, and more.

Parameters

NameTypeDefaultDescription
options?UseBarcodeDetectorOptions-Configuration options for barcode detection

Parameter Properties

options properties:

NameTypeDescription
formats?string[]Array of barcode formats to detect (defaults to all supported formats)

Return Type

UseBarcodeDetectorReturn
PropertyTypeDescription
detect(source: ImageBitmapSource) => Promise<DetectedBarcode[]>Detect barcodes in the provided image source
isSupportedbooleanWhether the Barcode Detection API is supported
supportedFormatsstring[]Array of supported barcode formats
isDetectingbooleanWhether detection is currently in progress
errorstring | nullError message if detection failed

Examples

Basic Barcode Detection

Detect barcodes from an image file input

1import { useBarcodeDetector } from '@usehooks/use-barcode-detector'; 2import { useRef } from 'react'; 3 4function BarcodeScanner() { 5 const { detect, isSupported, isDetecting, error } = useBarcodeDetector(); 6 const fileInputRef = useRef<HTMLInputElement>(null); 7 8 const handleFileSelect = async (event: React.ChangeEvent<HTMLInputElement>) => { 9 const file = event.target.files?.[0]; 10 if (!file) return; 11 12 try { 13 const barcodes = await detect(file); 14 console.log('Detected barcodes:', barcodes); 15 barcodes.forEach(barcode => { 16 console.log(`Format: ${barcode.format}, Value: ${barcode.rawValue}`); 17 }); 18 } catch (err) { 19 console.error('Detection failed:', err); 20 } 21 }; 22 23 if (!isSupported) { 24 return <div>Barcode detection not supported</div>; 25 } 26 27 return ( 28 <div> 29 <input 30 ref={fileInputRef} 31 type="file" 32 accept="image/*" 33 onChange={handleFileSelect} 34 disabled={isDetecting} 35 /> 36 {isDetecting && <p>Detecting...</p>} 37 {error && <p>Error: {error}</p>} 38 </div> 39 ); 40}

QR Code Detection

Detect only QR codes from camera stream

1import { useBarcodeDetector } from '@usehooks/use-barcode-detector'; 2import { useRef, useEffect } from 'react'; 3 4function QRScanner() { 5 const { detect, isSupported } = useBarcodeDetector({ 6 formats: ['qr_code'] 7 }); 8 const videoRef = useRef<HTMLVideoElement>(null); 9 const canvasRef = useRef<HTMLCanvasElement>(null); 10 11 useEffect(() => { 12 let stream: MediaStream; 13 14 const startCamera = async () => { 15 try { 16 stream = await navigator.mediaDevices.getUserMedia({ video: true }); 17 if (videoRef.current) { 18 videoRef.current.srcObject = stream; 19 } 20 } catch (err) { 21 console.error('Camera access failed:', err); 22 } 23 }; 24 25 startCamera(); 26 27 return () => { 28 if (stream) { 29 stream.getTracks().forEach(track => track.stop()); 30 } 31 }; 32 }, []); 33 34 const scanFrame = async () => { 35 if (!videoRef.current || !canvasRef.current) return; 36 37 const canvas = canvasRef.current; 38 const video = videoRef.current; 39 const ctx = canvas.getContext('2d'); 40 41 if (ctx) { 42 canvas.width = video.videoWidth; 43 canvas.height = video.videoHeight; 44 ctx.drawImage(video, 0, 0); 45 46 try { 47 const barcodes = await detect(canvas); 48 if (barcodes.length > 0) { 49 console.log('QR Code detected:', barcodes[0].rawValue); 50 } 51 } catch (err) { 52 console.error('Scan failed:', err); 53 } 54 } 55 56 requestAnimationFrame(scanFrame); 57 }; 58 59 if (!isSupported) { 60 return <div>Barcode detection not supported</div>; 61 } 62 63 return ( 64 <div> 65 <video ref={videoRef} autoPlay muted onLoadedMetadata={scanFrame} /> 66 <canvas ref={canvasRef} style={{ display: 'none' }} /> 67 </div> 68 ); 69}

Multiple Format Detection

Detect multiple barcode formats with detailed information

1import { useBarcodeDetector } from '@usehooks/use-barcode-detector'; 2import { useState } from 'react'; 3 4function MultiBarcodeScanner() { 5 const { detect, supportedFormats, isDetecting } = useBarcodeDetector(); 6 const [results, setResults] = useState<any[]>([]); 7 8 const handleImageUpload = async (event: React.ChangeEvent<HTMLInputElement>) => { 9 const file = event.target.files?.[0]; 10 if (!file) return; 11 12 try { 13 const barcodes = await detect(file); 14 setResults(barcodes); 15 } catch (err) { 16 console.error('Detection failed:', err); 17 setResults([]); 18 } 19 }; 20 21 return ( 22 <div> 23 <div> 24 <h3>Supported Formats:</h3> 25 <ul> 26 {supportedFormats.map(format => ( 27 <li key={format}>{format}</li> 28 ))} 29 </ul> 30 </div> 31 32 <input 33 type="file" 34 accept="image/*" 35 onChange={handleImageUpload} 36 disabled={isDetecting} 37 /> 38 39 {results.length > 0 && ( 40 <div> 41 <h3>Detected Barcodes:</h3> 42 {results.map((barcode, index) => ( 43 <div key={index}> 44 <p><strong>Format:</strong> {barcode.format}</p> 45 <p><strong>Value:</strong> {barcode.rawValue}</p> 46 <p><strong>Bounding Box:</strong> {JSON.stringify(barcode.boundingBox)}</p> 47 </div> 48 ))} 49 </div> 50 )} 51 </div> 52 ); 53}

Dependencies

react

Notes

  • Only available in browsers that support the Barcode Detection API (Chrome 83+)
  • Requires HTTPS in production environments
  • Supported formats vary by browser and platform
  • Image sources can be HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageBitmap, or File
  • Detection accuracy depends on image quality and barcode visibility

Implementation

1"use client"; 2 3import { useState, useCallback, useRef, useEffect } from "react"; 4 5interface DetectedBarcode { 6 boundingBox: DOMRectReadOnly; 7 cornerPoints: Array<{ x: number; y: number }>; 8 format: string; 9 rawValue: string; 10} 11 12interface UseBarcodeDetectorOptions { 13 formats?: string[]; 14} 15 16interface UseBarcodeDetectorReturn { 17 detect: (source: ImageBitmapSource) => Promise<DetectedBarcode[]>; 18 isSupported: boolean; 19 supportedFormats: string[]; 20 isDetecting: boolean; 21 error: string | null; 22} 23 24export const useBarcodeDetector = ( 25 options: UseBarcodeDetectorOptions = {} 26): UseBarcodeDetectorReturn => { 27 const [isDetecting, setIsDetecting] = useState(false); 28 const [error, setError] = useState<string | null>(null); 29 const [supportedFormats, setSupportedFormats] = useState<string[]>([]); 30 const detectorRef = useRef<any | null>(null); 31 32 const isSupported = 33 typeof window !== "undefined" && "BarcodeDetector" in window; 34 35 useEffect(() => { 36 if (!isSupported) return; 37 38 const initializeDetector = async () => { 39 try { 40 // Get supported formats 41 const formats = await ( 42 window as any 43 ).BarcodeDetector.getSupportedFormats(); 44 setSupportedFormats(formats); 45 46 // Create detector with specified formats or all supported formats 47 const detectorFormats = options.formats || formats; 48 detectorRef.current = new (window as any).BarcodeDetector({ 49 formats: detectorFormats, 50 }); 51 } catch (err) { 52 setError( 53 err instanceof Error 54 ? err.message 55 : "Failed to initialize barcode detector" 56 ); 57 } 58 }; 59 60 initializeDetector(); 61 }, [isSupported, options.formats]); 62 63 const detect = useCallback( 64 async (source: ImageBitmapSource): Promise<DetectedBarcode[]> => { 65 if (!isSupported || !detectorRef.current) { 66 throw new Error("Barcode detection is not supported"); 67 } 68 69 setIsDetecting(true); 70 setError(null); 71 72 try { 73 const barcodes = await detectorRef.current.detect(source); 74 return barcodes.map((barcode: any) => ({ 75 boundingBox: barcode.boundingBox, 76 cornerPoints: barcode.cornerPoints, 77 format: barcode.format, 78 rawValue: barcode.rawValue, 79 })); 80 } catch (err) { 81 const errorMessage = 82 err instanceof Error ? err.message : "Detection failed"; 83 setError(errorMessage); 84 throw new Error(errorMessage); 85 } finally { 86 setIsDetecting(false); 87 } 88 }, 89 [isSupported] 90 ); 91 92 return { 93 detect, 94 isSupported, 95 supportedFormats, 96 isDetecting, 97 error, 98 }; 99}; 100 101export default useBarcodeDetector; 102