Svelte is a JavaScript library meant explicitly for creating interactive UIs. Svelte compiles components into code that directly manipulates the DOM, unlike other frameworks such as Vue and React that relies on a virtual DOM for updates. Follow this guide to learn how to implement Dynamsoft Barcode Reader JavaScript SDK (hereafter called "the library") into a Svelte application using Vite. Note that in this sample we will use TypeScript.
In this guide, we will be using `dynamsoft-barcode-reader-bundle 11.4.2000.
Note:
If you're looking to integrate DBR-JS into a framework that we don't yet have a sample, don't worry! We have a comprehensive guide that provides detailed instruction and best practices for a seamless integration into any frameworks!
Additionally, we're here to help! Please don't hesitate to contact us for any support or questions you might have.
Make sure you have node installed. node 16.20.1 and svelte 4.2.12 are used in the example below.
npm install
npm run devThen open http://localhost:5173/ to view the sample app.
If you're planning to start the project from scratch, in this section, we will be creating a Svelte application with Vite utilizing the Dynamsoft Barcode Reader bundle sdk.
We'll be exploring how you could create a page that not only enables barcode scanning via a webcam or a built-in camera, but also decode barcodes from local images.
By the end of this guide, you'll have a good understanding of the SDK and be ready to discover more ways to use it!
npm create vite@latest my-app
<!-- Configurations -->
√ Select a framework: » Svelte
√ Select a variant: » TypeScriptcd my-app
npm install dynamsoft-barcode-reader-bundle@11.4.2000 -E/* /src/dynamsoft.config.ts */
import { CoreModule } from "dynamsoft-core";
import { LicenseManager } from "dynamsoft-license";
import "dynamsoft-barcode-reader";
// Configures the paths where the .wasm files and other necessary resources for modules are located.
CoreModule.engineResourcePaths.rootDirectory = "https://cdn.jsdelivr.net/npm/";
/** LICENSE ALERT - README
* To use the library, you need to first specify a license key using the API "initLicense()" as shown below.
*/
LicenseManager.initLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9");
/**
* You can visit https://www.dynamsoft.com/customer/license/trialLicense?utm_source=samples&product=dbr&package=js to get your own trial license good for 30 days.
* Note that if you downloaded this sample from Dynamsoft while logged in, the above license key may already be your own 30-day trial license.
* For more information, see https://www.dynamsoft.com/barcode-reader/docs/web/programming/javascript/user-guide/index.html?ver=11.4.2000&cVer=true#specify-the-license&utm_source=samples or contact support@dynamsoft.com.
* LICENSE ALERT - THE END
*/
// Optional. Preload .wasm file for reading barcodes. It will save time on the initial decoding by skipping the resource loading.
CoreModule.loadWasm();Note:
initLicense()specify a license key to use the library. You can visit https://www.dynamsoft.com/customer/license/trialLicense?utm_source=sample&product=dbr&package=js to get your own trial license good for 30 days.engineResourcePathstells the library where to get the necessary resources at runtime.
- Create a directory
componentsunder/src/
-
Create
VideoCapture.svelteunder/src/components/. TheVideoCapturecomponent helps decode barcodes via camera. -
In
VideoCapture.svelte, add code for initializing and destroying some instances. For our stylesheet (CSS) specification, please refer to our source code.
<!-- /src/components/VideoCapture.svelte -->
<script lang="ts">
import { onMount } from "svelte";
import "../dynamsoft.config"; // import side effects. The license, engineResourcePath, so on.
import { CameraEnhancer, CameraView } from "dynamsoft-camera-enhancer";
import { CaptureVisionRouter } from "dynamsoft-capture-vision-router";
import { MultiFrameResultCrossFilter } from "dynamsoft-utility";
const componentDestroyedErrorMsg = "VideoCapture Component Destroyed";
let cameraViewContainer: HTMLDivElement;
let resultText = "";
let resolveInit: () => void;
const pInit: Promise<void> = new Promise((r) => {
resolveInit = r;
});
let isDestroyed = false;
let cvRouter: CaptureVisionRouter;
let cameraEnhancer: CameraEnhancer;
onMount(() => {
(async () => {
try {
// Create a `CameraEnhancer` instance for camera control and a `CameraView` instance for UI control.
const cameraView = await CameraView.createInstance();
if (isDestroyed) {
throw Error(componentDestroyedErrorMsg);
} // Check if component is destroyed after every async
cameraEnhancer = await CameraEnhancer.createInstance(cameraView);
if (isDestroyed) {
throw Error(componentDestroyedErrorMsg);
}
// Get default UI and append it to DOM.
cameraViewContainer.append(cameraView.getUIElement());
// Create a `CaptureVisionRouter` instance and set `CameraEnhancer` instance as its image source.
cvRouter = await CaptureVisionRouter.createInstance();
if (isDestroyed) {
throw Error(componentDestroyedErrorMsg);
}
cvRouter.setInput(cameraEnhancer);
// Define a callback for results.
cvRouter.addResultReceiver({
onDecodedBarcodesReceived: (result) => {
if (!result.barcodeResultItems.length) return;
resultText = "";
console.log(result);
for (let item of result.barcodeResultItems) {
resultText += `${item.formatString}: ${item.text}\n\n`;
}
},
});
// Filter out unchecked and duplicate results.
const filter = new MultiFrameResultCrossFilter();
// Filter out unchecked barcodes.
filter.enableResultCrossVerification("barcode", true);
// Filter out duplicate barcodes within 3 seconds.
filter.enableResultDeduplication("barcode", true);
await cvRouter.addResultFilter(filter);
if (isDestroyed) {
throw Error(componentDestroyedErrorMsg);
}
// Open camera and start scanning single barcode.
await cameraEnhancer.open();
cameraView.setScanLaserVisible(true);
if (isDestroyed) {
throw Error(componentDestroyedErrorMsg);
}
await cvRouter.startCapturing("ReadSingleBarcode");
if (isDestroyed) {
throw Error(componentDestroyedErrorMsg);
}
} catch (ex: any) {
if ((ex as Error)?.message === componentDestroyedErrorMsg) {
console.log(componentDestroyedErrorMsg);
} else {
let errMsg = ex.message || ex;
console.error(ex);
alert(errMsg);
}
}
// distroy function will wait pInit
resolveInit!();
})();
// onBeforeUnmount
return async () => {
isDestroyed = true;
try {
await pInit;
cvRouter?.dispose();
cameraEnhancer?.dispose();
} catch (_) {}
};
});
</script>
<div>
<div
bind:this={cameraViewContainer}
style="width: 100%; height: 70vh; background: #eee;"
></div>
Results:<br />
<div class="results">{resultText}</div>
</div>Note:
- If you're looking to customize the UI, the UI customization feature are provided by the auxiliary SDK "Dynamsoft Camera Enhancer". For more details, refer to our User Guide
-
Create
ImageCapture.svelteunder/src/components/. TheImageCapturecomponent helps decode barcodes in an image. -
In
ImageCapture.svelte, add code for initializing and destroying some instances. For our stylesheet (CSS) specification, please refer to our source code.
<!-- /src/components/ImageCapture.svelte -->
<script lang="ts">
import { onMount } from "svelte";
import "../dynamsoft.config";
import { EnumCapturedResultItemType } from "dynamsoft-core";
import { type BarcodeResultItem } from "dynamsoft-barcode-reader";
import { CaptureVisionRouter } from "dynamsoft-capture-vision-router";
let pCvRouter: Promise<CaptureVisionRouter>;
let isDestroyed = false;
let resultText = "";
const captureImage = async (e: Event) => {
let files = [...(e.target! as HTMLInputElement).files!];
(e.target! as HTMLInputElement).value = ""; // reset input
resultText = "";
try {
const cvRouter = await (pCvRouter = pCvRouter || CaptureVisionRouter.createInstance());
if (isDestroyed) return;
for (let file of files) {
// Decode selected image with 'ReadBarcodes_ReadRateFirst' template.
const result = await cvRouter.capture(file, "ReadBarcodes_ReadRateFirst");
console.log(result);
if (isDestroyed) return;
// Print file name if there's multiple files
if (files.length > 1) {
resultText += `\n${file.name}:\n`;
}
for (let _item of result.items) {
if (_item.type !== EnumCapturedResultItemType.CRIT_BARCODE) {
continue; // check if captured result item is a barcode
}
let item = _item as BarcodeResultItem;
resultText += item.formatString + ": " + item.text + "\n"; // output the decoded barcode text
}
// If no items are found, display that no barcode was detected
if (!result.items.length) resultText += "No barcode found\n";
}
} catch (ex: any) {
let errMsg = ex.message || ex;
console.error(ex);
alert(errMsg);
}
};
onMount(() => {
// onBeforeUnmount. dispose cvRouter when it's no longer needed
return async () => {
isDestroyed = true;
if (pCvRouter) {
try {
(await pCvRouter).dispose();
} catch (_) {}
}
};
});
</script>
<div class="image-capture-container">
<div class="input-container">
<input type="file" multiple on:change={captureImage} accept=".jpg,.jpeg,.icon,.gif,.svg,.webp,.png,.bmp" />
</div>
<div class="result">{resultText}</div>
</div>-
On
/src/App.svelte, we will edit the component so that it offers buttons to switch components betweenVideoCaptureandImageCapture. -
Add following code to
App.svelte. For our stylesheet (CSS) specification, please refer to our source code.
<!-- /* src/App.svelte */ -->
<script lang="ts">
import VideoCapture from "./components/VideoCapture.svelte";
import ImageCapture from "./components/ImageCapture.svelte";
let mode = "video";
</script>
<main>
<div class="App">
<div class="title">
<h2 class="title-text">Hello World for Svelte</h2>
<img class="title-logo" src="https://www.svelte.cn/svelte-logo-horizontal.svg" alt="svelte" />
</div>
<div class="buttons-container">
<button
style="background-color: {mode === 'video' ? 'rgb(255, 174, 55)' : 'white'}"
on:click={() => {
mode = "video";
}}>Decode Video</button
>
<button
style="background-color: {mode === 'image' ? 'rgb(255, 174, 55)' : 'white'}"
on:click={() => {
mode = "image";
}}>Decode Image</button
>
</div>
{#if mode === "video"}
<VideoCapture></VideoCapture>
{:else}
<ImageCapture></ImageCapture>
{/if}
</div>
</main>- Try running the project.
npm run devIf you followed all the steps correctly, you will have a working page that turns one of the cameras hooked to or built in your computer or mobile device into a barcode scanner. Also, if you want to decode a local image, just click the Decode Image button and select the image you want to decode. Once barcodes are found, the results will show in a dialog.
If you have any questions, feel free to contact Dynamsoft support.