Step-by-Step Guide to Creating a Barcode Reader App for Salesforce AppExchange
While using Salesforce, you can easily extend your management system’s functionalities by installing apps from Salesforce AppExchange, the Salesforce marketplace. But what if you want to build a Salesforce app yourself? In this article, I’ll guide you through creating a barcode reader app for Salesforce from scratch.
Prerequisites
-
Include the Dynamsoft JavaScript Barcode SDK in your project.
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.6.42/dist/dbr.js"></script> -
Obtain a 30-day FREE trial license to try out the SDK.
Setting Up Your Salesforce Environment
Before diving into coding, you’ll need to configure your Salesforce account. Start by creating a Salesforce account.

Upon signing in, you’ll notice two interfaces: the classic UI and the Lightning UI. You can switch between them at any time.
Next, connect to a developer edition org in Environment Hub, which you’ll use to build apps with a developer account.

Don’t forget to retrieve your security token from My Settings, as it’s required when connecting to different organizations within the Salesforce partner community.

Installing Development Tools
To develop Salesforce apps, you’ll need to install Salesforce CLI and the Visual Studio Code extensions.
Salesforce CLI
Install the Salesforce Command Line Interface (CLI) from Salesforce CLI Installation

Visual Studio Code Extensions
Search for “salesforce pack” in Visual Studio Code and install the necessary extensions.

Building Your Salesforce App
In Visual Studio Code, press Ctrl+Shift+P and type “sfdx: create project” to create a new project named BarcodeReader:

Edit the project-scratch-def.json file and change the orgName according to your Salesforce account details:
{
"orgName": "Dynamsoft",
"edition": "Developer",
"features": [],
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
},
"securitySettings": {
"passwordPolicies": {
"enableSetPasswordInApi": true
}
},
"mobileSettings": {
"enableS1EncryptedStoragePref2": false
}
}
}
Authorize your org before deploying the local project to it.

Once authorized, the deployment option will be available in the context menu upon right-clicking.

Creating a Visualforce Page
Create a Visualforce page called DecodeFile using the SFDX command.

Deploy the page to Salesforce, where you can view it online.

After setting up the Visualforce page, add the barcode decoding logic using the provided JavaScript code snippet.
<apex:page >
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.6.42/dist/dbr.js"></script>
</head>
<body>
<h1>Dynamsoft JavaScript Barcode SDK</h1>
<p></p>
<div id="performance"></div>
<input type="file" id="barcode-file" onchange="loadfile()" accept=".jpg,.jpeg,.png,.bmp" />
<div>
<img id='image' />
</div>
<script>
Dynamsoft.DBR.BarcodeReader.license = "LICENSE-KEY";
var performanceReport = document.getElementById('performance');
var barcodereader;
(async () => {
barcodereader = await Dynamsoft.DBR.BarcodeReader.createInstance();
})();
var ratio = 0.6;
function loadfile() {
let name = document.getElementById('barcode-file');
var img = document.getElementById('image');
var reader = new FileReader();
reader.onload = function (evt) {
img.onload = function () {
console.log(img.width, img.height);
// load image to canvas
var canvas = document.createElement('canvas');
if (img.width > 1000 || img.height > 1000) {
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
}
else {
canvas.width = img.width;
canvas.height = img.height;
}
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
var buffer = context.getImageData(0, 0, canvas.width, canvas.height).data;
let decoding_start = Date.now();
barcodereader
.decodeBuffer(
buffer,
canvas.width,
canvas.height,
canvas.width * 4,
Dynamsoft.DBR.EnumImagePixelFormat.IPF_ARGB_8888
)
.then((results) => {
let decoding_end = Date.now();
performanceReport.innerHTML = "File name: " + name.files[0].name + ", time cost: " + (decoding_end - decoding_start) + " ms <br>";
console.log("File name: " + name.files[0].name + ", time cost: " + (decoding_end - decoding_start) + " ms");
let txts = [];
try {
let localization;
for (var i = 0; i < results.length; ++i) {
performanceReport.innerHTML += "Result: " + results[i].barcodeText + " <br>"
txts.push(results[i].barcodeText);
}
let out = txts.join(', ');
if (txts.length > 0) {
console.log(out);
}
else {
performanceReport.innerHTML += 'No barcode found'
console.log('No barcode found');
}
} catch (e) {
}
});
};
img.src = evt.target.result;
};
reader.readAsDataURL(name.files[0]);
};
</script>
</body>
</html>
</apex:page>
Note: You need to replace LICENSE-KEY with your own.
Save your changes and re-deploy the code. Here’s a preview of the Visualforce page.

You can also create another Visualforce page for decoding barcodes from a camera video stream and deploy it to Salesforce.
<apex:page>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.6.42/dist/dbr.js"></script>
<style>
#videoview {
position: relative;
width: 90%;
height: 64vh;
}
#videoContainer {
position: relative;
width: 100%;
height: 100%;
z-index: 1
}
</style>
</head>
<body>
<h1>Dynamsoft JavaScript Barcode SDK</h1>
<p></p>
<div class="select">
<a>Video source: </a>
<select id="videoSource"></select>
</div>
<div>
<button id="bt_start">Start</button>
<button id="bt_stop">Stop</button>
</div>
<div id="performance">N/A</div>
<div id="videoview">
<div class="dce-video-container" id="videoContainer"></div>
</div>
<script>
Dynamsoft.DBR.BarcodeReader.license = "LICENSE-KEY";
var resWidth = 1280, resHeight = 720;
var performanceReport = document.getElementById('performance');
var btStart = document.getElementById("bt_start");
var btStop = document.getElementById("bt_stop");
var decoding_start = 0;
var count = 0;
var averageTime = 0;
var total = 0;
var videoSelect = document.getElementById('videoSource');
var scanner = null;
var cameras = null;
var camerainfo = {};
(async () => {
scanner = await Dynamsoft.DBR.BarcodeScanner.createInstance();
scanner.setUIElement(document.getElementById('videoContainer'));
scanner._canvasMaxWH = 640;
// get camera source
cameras = await scanner.getAllCameras();
for (var i = 0; i < cameras.length; i++) {
let option = document.createElement('option');
option.text = cameras[i].label || 'camera ' + i;
camerainfo[option.text] = i;
videoSelect.appendChild(option);
}
scanner.onFrameRead = results => {
let decoding_end = Date.now();
if (decoding_start == 0) {
decoding_start = decoding_end;
count = 0;
total = 0;
averageTime = 0;
return;
}
let time_cost = decoding_end - decoding_start;
if (count == 60) {
count = 0;
total = 0;
averageTime = 0;
};
count += 1;
total += time_cost;
averageTime = total / count;
decoding_start = decoding_end;
// performanceReport.innerHTML = "";
if (results.length > 0) {
let txts = [];
try {
let localization;
for (var i = 0; i < results.length; ++i) {
performanceReport.innerHTML = "Type: " + results[i].barcodeFormatString + ", Value: " + results[i].barcodeText + ", average time cost: " + averageTime + " ms <br>";
txts.push(results[i].barcodeText);
console.log("Type: " + results[i].barcodeFormatString + ", Value: " + results[i].barcodeText + ", average time cost: " + averageTime + " ms");
}
let out = txts.join(', ');
} catch (e) {
}
}
else {
// console.log("No barcode found");
}
};
scanner.onUnduplicatedRead = (txt, result) => {
// console.log(txt, result);
};
await scanner.open();
})();
btStart.onclick = function () {
decoding_start = 0;
(async () => {
await scanner.open();
scanner.setResolution(resWidth, resHeight);
})();
}
btStop.onclick = function () {
(async () => {
await scanner.stop();
})();
}
videoSelect.onchange = function () {
decoding_start = 0;
(async () => {
if (scanner.isOpen()) {
await scanner.setCurrentCamera(cameras[camerainfo[videoSelect.value]]);
scanner.setResolution(resWidth, resHeight);
}
})();
}
</script>
</body>
</html>
</apex:page>

Adding Custom Tabs
With the Visualforce pages ready, create corresponding custom tabs in Salesforce to use them within the Salesforce window.


Creating the App
Now, group your custom tabs into an app that provides the required functionality as a unit.


Packaging for AppExchange
Finally, create a package containing your app to share the barcode decoding functionality publicly on AppExchange.


Publishing Your App to Salesforce AppExchange
Visit the Salesforce partner page to view your package. After completing the business plan and passing the security review, you can submit your package to Salesforce AppExchange.
