{"id":465,"date":"2025-09-23T08:57:58","date_gmt":"2025-09-23T08:57:58","guid":{"rendered":"https:\/\/datasymbol.com\/blog\/?p=465"},"modified":"2025-09-23T08:57:58","modified_gmt":"2025-09-23T08:57:58","slug":"barcode-scanner-web-sdk-for-flutter-app","status":"publish","type":"post","link":"https:\/\/datasymbol.com\/blog\/2025\/09\/23\/barcode-scanner-web-sdk-for-flutter-app\/","title":{"rendered":"Barcode Scanner Web SDK for Flutter App"},"content":{"rendered":"\n<figure class=\"wp-block-image alignright size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"648\" src=\"https:\/\/datasymbol.com\/blog\/wp-content\/uploads\/2025\/09\/barcode-scanner-flutter-app.jpg\" alt=\"\" class=\"wp-image-473\" style=\"width:600px\" srcset=\"https:\/\/datasymbol.com\/blog\/wp-content\/uploads\/2025\/09\/barcode-scanner-flutter-app.jpg 800w, https:\/\/datasymbol.com\/blog\/wp-content\/uploads\/2025\/09\/barcode-scanner-flutter-app-300x243.jpg 300w, https:\/\/datasymbol.com\/blog\/wp-content\/uploads\/2025\/09\/barcode-scanner-flutter-app-768x622.jpg 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p class=\"has-large-font-size\"><strong><a href=\"https:\/\/datasymbol.com\/barcode-web-sdk\/barcode-scanner-for-web.html\">What is DataSymbol Web SDK<\/a><\/strong><\/p>\n\n\n\n<p>DataSymbol\u2019s Web SDK enables barcode scanning via the browser, using WebAssembly + JS. In a Flutter Web app, since Flutter compiles to HTML\/JS\/CSS, we can integrate this SDK via JavaScript interop\u2014embedding the scanner UI over (or alongside) Flutter\u2019s canvas.<\/p>\n\n\n\n<p class=\"has-large-font-size\"><strong>When &amp; Why Use It<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You want barcode scanning in a <strong>web application<\/strong> (as opposed to mobile-native Flutter).<\/li>\n\n\n\n<li>You need support for many barcode types (Code128, EAN, QR, etc.).<\/li>\n\n\n\n<li>Prefer off-the-shelf SDK rather than writing your own JS barcode detection.<\/li>\n<\/ul>\n\n\n\n<p class=\"has-large-font-size\"><strong>Setup \/ Getting Started<\/strong><\/p>\n\n\n\n<p>Here are the steps to<a href=\"https:\/\/datasymbol.com\/barcode-web-sdk\/barcode-scanner-for-flutter-web-app.html\"> integrate DataSymbol Web SDK<\/a> into your Flutter Web project.<\/p>\n\n\n\n<p><strong>1. Download the SDK files<\/strong><\/p>\n\n\n\n<p>From the DataSymbol site, download the package. Out of all the files, you will need at least:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>datasymbol-sdk.wasm<\/li>\n\n\n\n<li>datasymbol-sdk-hlp.min.js <\/li>\n<\/ul>\n\n\n\n<p><strong>2. Put SDK files in the <\/strong><strong>web\/<\/strong><strong> folder of your Flutter project<\/strong><\/p>\n\n\n\n<p>Place datasymbol-sdk.wasm and datasymbol-sdk-hlp.min.js into the web directory of your Flutter project. This ensures they are served when the web app is built. <\/p>\n\n\n\n<p><strong>3. Add a JS file to control the scanner<\/strong><\/p>\n\n\n\n<p>Create a file called for example ds_create_scanner.js in web\/. This file will include the JS logic to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>load \/ initialize the scanner<\/li>\n\n\n\n<li>select the camera<\/li>\n\n\n\n<li>handle barcode and error callbacks<\/li>\n\n\n\n<li>embed the scanner viewport in the page at specific position\/size <\/li>\n<\/ul>\n\n\n\n<p><strong>4. Modify <\/strong><strong>web\/index.html<\/strong><strong><\/strong><\/p>\n\n\n\n<p>In &lt;head&gt; add script tags to load the SDK helper JS and your scanner setup file:<\/p>\n\n\n\n<p>&lt;script defer type=&#8221;text\/javascript&#8221; src=&#8221;datasymbol-sdk-hlp.min.js&#8221;&gt;&lt;\/script&gt;<\/p>\n\n\n\n<p>&lt;script type=&#8221;text\/javascript&#8221; src=&#8221;ds_create_scanner.js&#8221;&gt;&lt;\/script&gt;<\/p>\n\n\n\n<p>This ensures the scanner code is available. <\/p>\n\n\n\n<p class=\"has-large-font-size\"><strong>Integration with Flutter (Dart)<\/strong><\/p>\n\n\n\n<p>Since Flutter Web runs in browser, you can interoperate with JavaScript using Dart&#8217;s JS-interop features. The example from DataSymbol uses:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>@JS() to define external JS functions<\/li>\n\n\n\n<li>Dart extension types\/interface to map JS objects (e.g. result, error) into Dart usable types. <\/li>\n<\/ul>\n\n\n\n<p>Here are key Dart parts:<\/p>\n\n\n\n<p><strong>Define external JS functions<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"line-height:1.1\"><code>@JS()\nexternal void embedScanner(int x, int y, int width, int height);\n\n@JS()\nexternal void updateScannerPos(int x, int y, int width, int height);\n\n@JS()\nexternal void addScannerCallback(JSString funcName, JSFunction dsFuncCallback);<\/code><\/pre>\n\n\n\n<p><strong>Set up callbacks from JS<\/strong><\/p>\n\n\n\n<p>For example onBarcode and onError callback functions, which Dart side implements, then passed to JS via addScannerCallback. <\/p>\n\n\n\n<p><strong>Positioning \/ sizing the scanner viewport<\/strong><\/p>\n\n\n\n<p>The scanner overlay is an HTML element (div) positioned absolutely over\/above the Flutter canvas. To align it correctly, the Flutter side needs to know where a placeholder widget is on screen. Typically you:<\/p>\n\n\n\n<ul start=\"1\" class=\"wp-block-list\">\n<li>give that placeholder a GlobalKey<\/li>\n\n\n\n<li>get its position &amp; size (via RenderBox and findRenderObject, etc.)<\/li>\n\n\n\n<li>call embedScanner(&#8230;) with those values to position the JS viewport<\/li>\n\n\n\n<li>listen to metrics changes (window resize, orientation change) to adjust via updateScannerPos(&#8230;)<\/li>\n<\/ul>\n\n\n\n<p><strong>Displaying scan result<\/strong><\/p>\n\n\n\n<p>The result string (decoded barcode) is passed from JS callback. Dart updates UI accordingly.<\/p>\n\n\n\n<p class=\"has-large-font-size\"><strong>Sample Flow<\/strong><\/p>\n\n\n\n<p>Putting it all together, here is a rough flow of what happens when your app runs in browser:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Flutter loads; UI contains a placeholder (e.g. SizedBox) where scanner should appear.<\/li>\n\n\n\n<li>JS SDK gets loaded (datasymbol-sdk-hlp.min.js) and your ds_create_scanner.js sets up functions.<\/li>\n\n\n\n<li>When Flutter side is first ready (after layout), it:\n<ul class=\"wp-block-list\">\n<li>Registers the JS callbacks (for barcode, for error)<\/li>\n\n\n\n<li>computes position &amp; size of placeholder<\/li>\n\n\n\n<li>calls embedScanner(&#8230;)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>JS:\n<ul class=\"wp-block-list\">\n<li>finds available video devices (cameras)<\/li>\n\n\n\n<li>picks one (back camera on mobile, or suitable on desktop)<\/li>\n\n\n\n<li>initializes scanner with settings (barcode types, timeouts, etc.)<\/li>\n\n\n\n<li>starts video stream and recognition<\/li>\n\n\n\n<li>when barcode detected, fires onBarcode event<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Flutter (Dart) receives event, updates UI with barcode string result. Also handles errors.<\/li>\n\n\n\n<li>If window is resized \/ device orientation changes or UI layout changes, Flutter recomputes placeholder position &amp; size, calls updateScannerPos(&#8230;) so JS overlay follows.<\/li>\n<\/ol>\n\n\n\n<p class=\"has-large-font-size\"><strong>Example Code Snippets<\/strong><\/p>\n\n\n\n<p>Here\u2019s a summary (simplified) of typical code:<\/p>\n\n\n\n<p><strong>js: ds_create_scanner.js<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"line-height:1.1\"><code>var _scannerVariables = { \u2026 };\n\nfunction onDSBarcode (barcodeResult) {\n  \u2026 call _scannerVariables.onBarcode callback \u2026\n}\n\nfunction onDSError(err) {\n  \u2026 call _scannerVariables.onError callback \u2026\n}\n\nfunction CreateScanner() {\n  \/\/ settings: key, frameTimeout, camera, barcode types etc.\n  DSScanner.Create(scannerSettings);\n}\n\nfunction embedScanner(x, y, width, height) {\n  \/\/ create div with id, style (position, size etc.)\n  \/\/ append to document.body\n  \/\/ after that call GetVideoDevices, then CreateScanner etc.\n}\n\nfunction updateScannerPos(x, y, width, height) {\n  \/\/ adjust style.left\/top\/width\/height of the scanner div\n}\n\nfunction addScannerCallback(funcName, dsFuncCallback) {\n  \u2026\n}<\/code><\/pre>\n\n\n\n<p><strong>dart: main.dart<\/strong> (abridged)<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"line-height:1.1\"><code>import 'dart:js_interop';\nimport 'package:flutter\/material.dart';\n\n@JS()\nexternal void embedScanner(int x, int y, int width, int height);\n@JS()\nexternal void updateScannerPos(int x, int y, int width, int height);\n@JS()\nexternal void addScannerCallback(String funcName, JSFunction dsFuncCallback);\n\nvoid onDSBarcode(DSBarcodeResult dr) {\n  \/\/ handle barcode\n}\n\nvoid onDSError(DSBarcodeError err) {\n  \/\/ handle error\n}\n\nRectangle&lt;int&gt; getBarcodeViewBox() {\n  \/\/ use GlobalKey, RenderBox, localToGlobal to get x,y,width,height\n}\n\nvoid startUpFunction() {\n  addScannerCallback('onError', onDSError.toJS);\n  addScannerCallback('onBarcode', onDSBarcode.toJS);\n  var rc = getBarcodeViewBox();\n  embedScanner(rc.left, rc.top, rc.width, rc.height);\n}<\/code><\/pre>\n\n\n\n<p class=\"has-large-font-size\"><strong>Advantages &amp; Limitations<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Advantages<\/strong><\/td><td><strong>Limitations \/ Challenges<\/strong><\/td><\/tr><\/thead><tbody><tr><td>Supports many barcode types out-of-the-box.<\/td><td>Positioning overlay exactly may be finicky\u2014especially across browsers or when UI layout changes.<\/td><\/tr><tr><td>Uses WebAssembly, likely good performance.<\/td><td>On some browsers\/mobile devices, camera permission or compatibility issues may arise.<\/td><\/tr><tr><td>Reuses JS\/SDK code; less reinventing barcode detection.<\/td><td>The overlay is separate from Flutter\u2019s canvas, so interactivity or layout integration (z-order, responsiveness) takes extra work.<\/td><\/tr><tr><td>Good for web targets where native plugins don\u2019t work.<\/td><td>File size, load time: wasm + JS may add bulk. Also latency or frame rates depend on camera and device.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-large-font-size\"><strong>Tips &amp; Best Practices<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Make sure to handle permissions: the browser will ask for camera access. Provide fallback or user guidance if denied.<\/li>\n\n\n\n<li>When building responsive UI, always recalc the scanner viewport size\/position when layout changes. E.g. listen to window resize, orientation change, after Flutter\u2019s build\/layout.<\/li>\n\n\n\n<li>Provide feedback to user during loading (\u201cscanner loading\u2026\u201d) so they know something is happening.<\/li>\n\n\n\n<li>For performance, choose a reasonable resolution for the camera (e.g. don\u2019t always use max resolution if not needed).<\/li>\n\n\n\n<li>Limit the barcode types to only the ones you need (not everything) to speed up decoding.<\/li>\n\n\n\n<li>Test across browsers (Chrome, Firefox, Safari) and devices (mobile, tablet, desktop) to check camera support.<\/li>\n<\/ul>\n\n\n\n<p class=\"has-large-font-size\"><strong>Summary<\/strong><\/p>\n\n\n\n<p>Using DataSymbol Web SDK in a Flutter Web app is quite feasible and they provide a detailed example. The key is embedding the JS SDK and overlay via HTML, then using Dart\u2019s JS interop to manage callbacks and layout. With careful handling of positioning, resizing, permissions and UI feedback, you can build a solid barcode scanning feature for web.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<br \/>\n<!-- READY TO GET STARTED START --><\/p>\n<div class='blue_rect blue_rect1' style='margin-top:3em; padding:2em;'>\n<h1 class='h15class'>Ready to get started?<\/h1>\n<div class='v18' style='width:60%'>\n\t\tIntegrate the DataSymbol Web SDK into your Web application in under an hour. Check out our tutorials, documentation, source code, or download the demo app to get started right away.\n\t<\/div>\n<p>\t<a class=\"anybutton anybutton3\" href=\"https:\/\/www.datasymbol.com\/barcode-web-sdk\/barcode-scanner-for-web.html\">Barcode Scanner Web SDK<\/a>\n<\/div>\n<p><!-- READY TO GET STARTED STOP --><br \/>\n","protected":false},"excerpt":{"rendered":"<p>What is DataSymbol Web SDK DataSymbol\u2019s Web SDK enables barcode scanning via the browser, using WebAssembly + JS. In a Flutter Web app, since Flutter compiles to HTML\/JS\/CSS, we can integrate this SDK via JavaScript interop\u2014embedding the scanner UI over (or alongside) Flutter\u2019s canvas. When &amp; Why Use It Setup \/ Getting Started Here are [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":473,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-465","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-barcode-scanner-web-sdk"],"_links":{"self":[{"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/posts\/465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/comments?post=465"}],"version-history":[{"count":7,"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/posts\/465\/revisions"}],"predecessor-version":[{"id":474,"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/posts\/465\/revisions\/474"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/media\/473"}],"wp:attachment":[{"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/media?parent=465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/categories?post=465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/datasymbol.com\/blog\/wp-json\/wp\/v2\/tags?post=465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}