Search any Capacitor forum for barcode scanning and one bug dominates: the camera preview is invisible. The classic approach renders the camera behind the web view and requires your entire app to be transparent — which works until an Ionic modal, a page transition, or a dark theme paints a background over it.
We took a different route with the embedded mode of the Capacitor Barcode Scanner plugin: the camera preview is a native view positioned inside your app layout, above the web view, so HTML can never cover it by accident.
Position the camera with a placeholder element
Your markup reserves the space, and the element's bounding rectangle becomes the frame:
import { BarcodeScanner, LensFacing } from '@capawesome-team/capacitor-barcode-scanner';
const getScanFrame = () => {
const rect = document.querySelector('#scanner').getBoundingClientRect();
return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
};
await BarcodeScanner.addListener('barcodesScanned', (event) => {
console.log('Scanned barcodes:', event.barcodes);
});
await BarcodeScanner.startScan({
frame: getScanFrame(),
lensFacing: LensFacing.Back,
});
Detected barcodes stream in continuously until stopScan(). A duplicateTimeout (default 1500 ms) prevents the same barcode from flooding your handler, formats restricts detection to what you expect, and detectionArea limits detection to a region within the frame.
Keep the frame in sync
The native view doesn't reflow with your CSS, so update it when the layout changes:
window.addEventListener('resize', async () => {
await BarcodeScanner.setScanFrame({ frame: getScanFrame() });
});
Overlays are an explicit opt-in
If your design needs HTML drawn over the camera (a viewfinder, detection markers), set placement: PreviewPlacement.Behind and the preview renders behind the web view. That mode has the same transparency requirement as the classic approach — but now it's a scoped choice for one screen you design around, not a global precondition for scanning at all.
It works on the web, too
The embedded mode and readBarcodesFromImage(...) are supported on the web via the BarcodeDetector API (with a recommended polyfill for browsers without it). Torch, zoom, and the ready-made fullscreen scanner are native-only.
The full guide also covers torch and zoom control, camera selection, the themeable fullscreen scanner, and migrating from the ML Kit Barcode Scanning plugin.
Top comments (0)