1D & 2D Barcodes
RepositoryI created this project in order to gain more experience with the NextJS framework. With this web app you can generate different types of 1 and 2 dimensional barcodes, such as QR Codes, EAN-13 Codes, Code 128 codes or Data Matrix. This web app also allows you to to scan your previously generated codes and other codes. For the styling of the web app I chose the Tailwind CSS library for inline styling and in general shortened styling.
Barcode Component
This React component takes in props and based off of these props it generates a barcode. With the prop chosenOption you can define what type of code you want. The prop value defines the content of the barcode. To generate the barcodes I used the bwipjs library. At the end, this component returns either the successfully rendered barcode or an error message.
1interface BarCodeProps {
2 chosenOption: string;
3 value: string;
4 onRendered?: (canvas: HTMLCanvasElement) => void;
5}
6
7export default function BarCode({chosenOption, value, onRendered}: BarCodeProps) {
8 const canvasRef = useRef<HTMLCanvasElement>(null);
9 const [error, setError] = useState<string | null>(null);
10
11 useEffect(() => {
12 setError(null);
13 if (!canvasRef.current) return;
14
15 try {
16 bwipjs.toCanvas(canvasRef.current, {
17 bcid: chosenOption,
18 text: value,
19 scale: 3,
20 includetext: true,
21 textxalign: 'center',
22 });
23 if (onRendered) {
24 onRendered(canvasRef.current);
25 }
26 } catch (e: any) {
27 console.error("Barcode generation error:", e);
28 setError(e.message || 'Failed to generate barcode.');
29 }
30 }, [value, chosenOption, onRendered])
31
32 return (
33 <div className="w-full h-auto border rounded-lg p-4 bg-white flex items-center justify-center">
34 {error ? (
35 <p className="text-red-500 text-center text-sm font-medium">{error}</p>
36 ) : (
37 <canvas ref={canvasRef} className="w-full h-auto" />
38 )}
39 </div>
40 );
41}
getCameraStream()
This function is part of my Camera component. It creates a visual input field for the camera, captures the content of the video feed and then decodes the barcode. For the decoding of the barcode I use the popular @zxing multi code reader library. If the camera decodes successfully, it sets the value of the barcode, if not, it will return a detailed error message which also shows what kind of error.
1const codeReader = new BrowserMultiFormatReader();
2let active = true;
3
4const getCameraStream = async () => {
5 try {
6 console.log("Requesting camera access...");
7
8 const constraints = {
9 audio: false,
10 video: {
11 facingMode: { ideal: "environment" },
12 width: { min: 640, ideal: 1280, max: 1920 },
13 height: { min: 480, ideal: 720, max: 1080 },
14 frameRate: { ideal: 30 },
15 },
16 };
17
18 let videoStream;
19 try {
20 videoStream = await navigator.mediaDevices.getUserMedia(constraints);
21 } catch (idealError) {
22 console.log("Ideal constraints failed, trying more relaxed constraints");
23 videoStream = await navigator.mediaDevices.getUserMedia({
24 audio: false,
25 video: {
26 facingMode: "environment",
27 width: { min: 320, ideal: 640 },
28 height: { min: 240, ideal: 480 },
29 },
30 });
31 }
32
33 console.log("Camera stream obtained:", videoStream);
34 setHasPermission(true);
35
36 if (videoRef.current) {
37 videoRef.current.srcObject = videoStream;
38
39 codeReader.decodeFromVideoDevice(
40 null,
41 videoRef.current,
42 (result, err) => {
43 if (active && result) {
44 console.log("Barcode detected:", result.getText());
45 setBarcode(result.getText());
46 }
47 },
48 );
49 }
50 } catch (e: any) {
51 console.error("Camera access failed:", e.name, e.message);
52 setError(`Camera access failed: ${e.name} – ${e.message}`);
53
54 if (e.name === "NotAllowedError") {
55 setError("Please allow camera access in your browser settings");
56 } else if (
57 e.name === "NotFoundError" ||
58 e.name === "OverconstrainedError"
59 ) {
60 setError("No suitable camera found. Please try with a different device.");
61 } else {
62 setError("Failed to access camera: " + e.message);
63 }
64 }
65};
Live Demonstration
Live DemoYou can try the web app yourself by clicking on the button. You will need to allow camera access on the reader. From personal experience I noticed the web app does not always work on Android devices.
Video Demonstration
This video requires optional cookies (YouTube).