I’m trying to integrate a QR/Barcode scanner on my Wix site using the html5-qrcode library inside a Custom Element.
The scanner works and detects QR codes.
Problems I’m facing:
- The camera stays open after navigating away from the page.
class QRScanner extends HTMLElement {
constructor() {
super();
const style = document.createElement("style");
style.textContent = `
#reader {
width: 100%;
height: 100%;
border-radius: 5px;
background-color: #989AAD;
display: flex;
justify-content: center;
align-items: center;
}
`;
const container = document.createElement("div");
const uniqueId = "reader-" + Math.random().toString(36).substr(2, 9);
container.id = uniqueId;
this.appendChild(style);
this.appendChild(container);
this.readerId = uniqueId;
this.html5Qrcode = null;
this.isRunning = false;
}
static get observedAttributes() {
return ["command"];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "command") {
if (newValue === "start") this.startScanner();
else if (newValue === "stop") this.stopScanner();
}
}
async disconnectedCallback() {
await this.stopScanner();
}
async startScanner() {
if (this.isRunning) return;
if (!this.html5Qrcode) {
const script = document.createElement("script");
script.src = "https://unpkg.com/html5-qrcode@2.3.8/html5-qrcode.min.js";
script.onload = () => {
this.html5Qrcode = new Html5Qrcode(this.readerId);
this._beginScan();
};
document.head.appendChild(script);
} else {
this._beginScan();
}
}
async _beginScan() {
if (!this.html5Qrcode) return;
this.isRunning = true;
try {
await this.html5Qrcode.start(
{ facingMode: "environment" },
{ fps: 10, qrbox: { width: 300, height: 300 } },
(decodedText) => {
this.dispatchEvent(new CustomEvent("scanResult", { detail: decodedText }));
this.stopScanner();
},
() => {}
);
} catch (err) {
this.dispatchEvent(new CustomEvent("cameraError", { detail: err }));
}
}
async stopScanner() {
if (this.html5Qrcode && this.isRunning) {
try {
await this.html5Qrcode.stop();
await this.html5Qrcode.clear();
} catch (e) {
console.warn("Scanner already stopped:", e);
}
this.isRunning = false;
}
}
}
customElements.define("qr-scanner2", QRScanner);

