JavaScript Read Barcode Country Of Origin

A picture of a phone showing a barcode to signify reading the country of origin via JavaScript

Live stream set for 2025-04-18 at 14:00:00 Eastern

Ask questions in the live chat about any programming or lifestyle topic.

This livestream will be on YouTube or you can watch below.

Identify Parsed Barcodes

A barcode is a method of representing machine-readable images consisting of black and white bars. Barcodes can identify the country of origin of the manufacturing company, but may not indicate where the product is made. GS1 is a non-profit international organization assigning unique numbers found in barcodes.

In a 1D barcode, data is scanned in a linear sequence using a series of vertical lines and spaces of varying widths to encode data. There are many different types of 2D barcodes such as QR code and Aztec code. QR codes are matrix barcodes that can contain alphanumeric and binary data. A popular use of QR codes is to share a link to a website for people with mobile devices. A popular use for scanning barcodes is to find the original country where the product was made.

The Barcode Detection API is a browser-native API designed to detect and decode barcodes in real-time using a device’s camera or video input. Barcode recognition within web apps unlocks a variety of use cases through supported barcode formats. QR codes for online payments, web navigation or establishing social media connections, Aztec codes to scan boarding passes and shopping apps can use EAN or UPC barcodes to compare prices of physical items. The MDN Web Docs on Barcode Detection API lists the supported barcode formats.

As of Spring 2025, no major desktop web browser supports the Barcode Detection API without a polyfill. The API is available of most major web browsers for Android.

In this tutorial, a detection mechanism will be used to conditionally load a pollyfill if applicable. Supported formats will be output along with the decoded result. Permission is required to access the camera, so it must be secure connection unless it is on the same workstation where localhost is allowed in the URL.

Requirements For Locally Hosted PWA

Glossary:

Polyfill

Implements a new standard feature that is not natively supported.

Hyperlink

Digital reference providing direct access to data by clicking, tapping or hovering.

1D

One-dimensional or linear.

2D

Two-dimensional developed, using geometric patterns like rectangles, dots, and hexagons.

Data Matrix

Two-dimensional barcode with uniquely generated patterns of square modules.

GS1 Composite

Two-dimensional barcode with 2 components, top for batch codes or expiry and bottom for item identification number.

Common Barcodes

Popular Barcodes
Name Description Example
1D Barcode Scanned horizontally and can hold 85 characters. Universal Product Code (UPC).
2D Barcode Scanned horizontally and vertically and can hold 7089 characters. QR Code.
2D Barcode Scanned horizontally and vertically and can hold 7089 characters. Aztec Code.
2D Barcode Scanned horizontally and vertically and can hold 7089 characters. Data matrix.
2D Barcode Scanned horizontally and vertically and can hold 7089 characters. GS1 Composite code.
Name Description Example

Scanning Devices

Recording Devices
Name Description Recording Power
Sony Xperia XA1 Ultra Updated to Android 8.0 and latest web browser. Takes photos and videos on front and back cameras. USB Type-C 2.0 10W charging
Samsung Galaxy S21 FE 5G Updated to Android 14.0 and default camera application. Takes photos and videos on front and back cameras. USB Type-C 2.0 <25W charging
Logitech HD Webcam C525 External webcam connected to workstation via USB cable. Takes audio, photos and videos on front camera. USB 2.0 <2.5W draw
Name Description Example

Generate QR Codes Via Libqrencode

# Create Text Link In QR Code #
qrencode -o qrcodel.png 'https://ojambo.com'

Generate QR Codes Via Zint Barcode Studio

# Create Text Link In QR Code #
zint -b QRCODE -o qrcodez.png -d "https://ojambo.com"

Stunnel Configuration

# Create Domain And IP Address Configuration File #
cat > stunnel.conf << 'EOF'
[https]
accept = 192.168.1.22:8443
connect = 192.168.1.22:8000
cert = stunnel.pem
EOF

Start Stunnel And PHP Web Server

# Start Stunnel And Web Server #
stunnel stunnel.conf & php -S 192.168.1.22:8000

HTML Barcode Scanner

<!DOCTYPE html>
<html>
	<head>
		<title>Barcode Reader</title>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<style>
			video { width:100%; height: auto; max-height: 100%; }
			i { word-wrap: break-word; display: block; }
		</style>
	</head>
	<body>
		<i></i>
		<em></em>
		<b></b>
		<svg class="fullscreen bounding-box"></svg>
      <video class="fullscreen" muted playsinline></video>		
		<script></script>
	</body>
</html>

JavaScript Barcode Scanner With Optional Polyfill

(() => {
	let str = null;
	let iid = null;
	let jsn = null;
	let bit = 1000;
	let vid = document.querySelector('video');
	let b = document.querySelector('b');
	let i = document.querySelector('i');
	let em = document.querySelector('em');
	let svg = document.querySelector('svg');
	let cts = {
		video: {
			facingMode: { ideal: 'environment' }
		},
		audio: false
	};
	let fmt = {
		formats: [
			'aztec',
			'code_128',
			'code_39',
			'code_93',
			'codabar',
			'data_matrix',
			'ean_13',
			'ean_8',
			'itf',
			'pdf417',
			'qr_code',
			'upc_a',
			'upc_e'
		]
	};
	navigator.mediaDevices.getUserMedia(cts).then((stream) => {
		str = stream;
		vid.srcObject = stream;
		vid.play();
	});
	let bet = (n, range) => {
		return n >= range[0] && n <= range[1];
	};
	let ckCTRY = (cds, str) => {
		let num = Number(str.slice(0, 3));
		if ( !jsn.country.hasOwnProperty(num) ) {
			cds.forEach((key) => {
				let nums = key.split('–').map(Number);
				if ( bet(num, nums) ) {
					b.innerHTML = jsn.country[key];
					return;
				}
			});
		}
	};
	let dec = () => {
		try {
			jsn = {
				"country": {
					"001–019":"UPC-A compatible -  United States",
					"020–029":"UPC-A compatible - Used to issue restricted circulation numbers within a geographic region",
					"030–039":"UPC-A compatible -  United States drugs (see United States National Drug Code)",
					"040–049":"UPC-A compatible - Used to issue restricted circulation numbers within a company",
					"050–059":"UPC-A compatible - GS1 US reserved for future use",
					"060–099":"UPC-A compatible -  United States",
					"100–139":"United States",
					"380":"Bulgaria",
					"754–755":"Canada",
					"750":"Mexico"
				}
			};
			let rkeys = Object.keys(jsn.country).filter(key => key.includes('–')); // Country Coder

			BarcodeDetector.getSupportedFormats().then((suf) => {
				let kep = [];
				suf.forEach((smt) => {
					if ( fmt.formats.includes(smt) ) {
						kep.push(smt);
					}
				});
				fmt.formats = kep;
				i.innerHTML = JSON.stringify(fmt.formats);
				let bcd = new BarcodeDetector(fmt);
				iid = setInterval(() => {
					bcd.detect(vid)
					.then(bds => {
						if ( JSON.stringify(bds) !== '[]' ) {
							b.innerHTML = '';
							bds.forEach((bc) => { 
								em.innerHTML = (bc.rawValue);
								b.innerHTML = JSON.stringify(bc);
								// Country Detector
								ckCTRY(rkeys, bc.rawValue);
							});
						}
					})
					.catch((err) => console.error(err));
				}, bit);
			});
		} catch (error) {
			console.error("An error occured:", error);
		}
	};
	let lmd = async () => {
		let { BarcodeDetectorPolyfill } = await import('https://fastly.jsdelivr.net/npm/barcode-detector@3/dist/es/polyfill.min.js');
		try {
			 window['BarcodeDetector'].getSupportedFormats();
		} catch {
			 window['BarcodeDetector'] = BarcodeDetectorPolyfill();
		}
		dec();
	};
	if ( !('BarcodeDetector' in window) ) {
		lmd();
	} else {
		dec();
	}

})();

Download

The Libqrencode library can be downloaded from Libqrencode Library and installed on your workstation.

The Zint library can be downloaded from Zint Library and installed on your workstation.

The Stunnel tunneling service can be downloaded from Stunnel and installed on your workstation.

The PHP scripting language can be downloaded from PHP and installed on your workstation.

Explanation

  1. Generate a self-signed Certificate if using a LAN.
  2. The scanning device must have a camera.
  3. The API will not work is camera access is not granted.
  4. The formats are dependent on web browser support.
  5. Use a polyfill for desktop and mobile devices that lack Barcode Detection API support.
  6. The first output will be the supported formats.
  7. The second output will be the value of the decoded barcode.
  8. The third output will be the entire decoded results.
  9. The value of the decoded barcode will be compared to GS1 assigned EAN/UPC barcodes.

Desktop Web Browser Barcode UPC Country Scanner
Desktop Web Browser Barcode UPC Country Of Origin Scanner Results Via Pollyfill

Mobile Web Browser Barcode UPC Country Scanner
Mobile Web Browser Barcode UPC Country Of Origin Scanner On Android Device


Usage

  • You may use the Libqrencode command line tool to generate QR codes using the default settings.
  • You can use the zint command line tool or Zint Barcode Studio GUI to generate barcodes using the default settings.
  • You may use the PHP built-in web server and Stunnel for tunneling secure connections.
  • You might need to use a polyfill if you are using a web browser that does not support the API natively.
  • The Barcode Detection API is limited to 13 formats and not all might be supported in different web browsers.

Open Source

Libqrencode is licensed under the terms of the GNU Lesser General Public License (LGPL) version 2.1. The copyleft license comes with strict rules and requirements to ensure the software remains free and open-source. It allows commercial use, modification, distribution, and allows making derivatives proprietary, consult the license for more specific details.

Zint, including the encoding library, is released under a dual license. The encoding library is released under the BSD (3 clause) license, while the GUI, Zint Barcode Studio, and the CLI are released under the GNU General Public License version 3 or later. The permissive license requires the preservation of the copyright notice and disclaimer, while the copyleft license comes with strict rules and requirements to ensure the software remains free and open-source. It allows commercial use, modification, distribution, and allows making derivatives proprietary, consult the license for more specific details.

Stunnel is licensed under the terms of the GNU General Public License (GPL) version 2 or later with OpenSSL exception. The copyleft license comes with strict rules and requirements to ensure the software remains free and open-source. It allows commercial use, modification, distribution, and allows making derivatives proprietary, consult the license for more specific details.

The PHP License is an open-source under which the PHP scripting language is released. The permissive license has conditions requiring preservation of copyright and license notices. Redistribution is permitted in source or binary form with or without modifications, consult the license for more specific details.

Conclusion:

The Barcode Detection API is browser-native and is designed to detect and decode barcodes using the device camera or video input. It supports 13 barcode formats including the most popular QR codes. A polyfill can be used for web browsers that lack native support. Easily parse UPC barcodes codes to obtain the country of origin of the manufacturing company using JavaScript.

If you enjoy this article, consider supporting me by purchasing one of my OjamboShop.com Online Programming Courses or publications at Edward Ojambo Programming Books or simply donate here Ojambo.com Donate

References:

Leave a Reply

Your email address will not be published. Required fields are marked *