Skip to content

How to build a Next.js Barcode Scanner web app with TypeScript

Chandu February 6, 2025 9 mins read
app store

Thanks to the Scanbot Web Barcode Scanner SDK‘s Ready-to-Use UI Components, you can add barcode scanning functionalities to your website or web app in a matter of minutes. This tutorial will demonstrate how to integrate the SDK using Next.js.

Scanning a single barcode with our JavaScript barcode scanner
Scanning a single barcode
Scanning multiple barcodes with our Next.js barcode scanner
Scanning multiple barcodes with the AR overlay

Requirements

  • Node.js (version 18.18 or higher)

Step 1: Set up the project

We’ll be using Next.js to set up our project.

Open a terminal and create a new Next.js project with the following command:

npx create-next-app@latest

You will be asked to name your project. For this tutorial, let’s go with “scanbot-nextjs-tut”.

When prompted to specify the features you want to use, answer Yes to using TypeScript. For this tutorial, we’ll also go with putting the code inside a “src” directory and using App Router. Feel free to decline the rest, since we won’t need them for this tutorial.

Now run:

cd scanbot-nextjs-tut
npm install
npm run dev

Step 2: Initialize the SDK

Open another terminal, navigate to your project folder, and install the scanbot-web-sdk package with the following command:

npm i scanbot-web-sdk

The SDK contains WebAssembly binaries that should be hosted on your server. We ship these binaries with the npm package. Since Node.js doesn’t copy the binaries to the target automatically, you need to manually copy them to the desired destination (we recommend the public asset directory).

You can quickly copy them from node_modules to a folder called wasm in the public asset directory using the following command:

mkdir -p public/wasm && cp -r node_modules/scanbot-web-sdk/bundle/bin/barcode-scanner/* public/wasm

💡 To ensure these files are always copied to the same directory for all users and updated when the SDK itself is updated, you can add the command as a post-installation script to your package.json:

"postinstall": "mkdir -p public/wasm && cp -r node_modules/scanbot-web-sdk/bundle/bin/barcode-scanner/* public/wasm"

Next, open src/app/page.tsx and replace the file’s contents with the following:

import type ScanbotSDK from "scanbot-web-sdk/UI";

export default function Home() {
  return (
    <div>
        <p> Scanbot Next.js Example </p>
    </div>
  );
}

We need to initialize ScanbotSDK within page.tsx. You have the option of leaving the licenseKey empty to use a trial mode that works for 60 seconds per session or getting a free 7-day trial by submitting the trial license form on our website.

Your page.tsx should now look like this:

import { useEffect } from "react";
import type ScanbotSDK from "scanbot-web-sdk/UI";

export default function Home() {

  let ScanbotSdk: typeof ScanbotSDK;

  async function loadSDK() {
    // Use dynamic inline imports to load the SDK, else Next will load it into the server bundle
    // and attempt to load it before the 'window' object becomes available.
    // https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading
    ScanbotSdk = (await import('scanbot-web-sdk/UI')).default;

    await ScanbotSdk.initialize({
      licenseKey: "",
      enginePath: "/wasm/",
    });
  }

  // initialize the Scanbot Barcode SDK
  useEffect(() => {
    loadSDK();
  });

  return (
    <div>
        <p> Scanbot Next.js Example </p>
    </div>
  );
}

Step 3: Create the barcode scanner

First, we’ll need to create the configuration that we’ll use for the barcode scanner in page.tsx.

To create the configuration, we can call a method that returns an instance of the configuration object, which we can then modify as needed:

const config = new ScanbotSdk.UI.Config.BarcodeScannerScreenConfiguration();

This config object will be what we use to make changes to the RTU UI. However, for now, let’s just use it to create our barcode scanner:

await ScanbotSdk.UI.createBarcodeScanner(config);

Now, let’s assign the scanner to a variable and wrap it within an asynchronous function so we can easily assign it to a button within our page.tsx. This allows us to easily trigger the scanner with a button press in our application.

Let’s name the variable “result”, since it will store the outcome returned by createBarcodeScanner.

 async function startBarcodeScanner() {
    const config = new ScanbotSdk.UI.Config.BarcodeScannerScreenConfiguration();
    const result = await ScanbotSdk.UI.createBarcodeScanner(config);
}

To trigger the scanner with a button press, we add a button and assign the startBarcodeScanner function to its onClick event:

return (
    <div>
        <p> Scanbot Next.js Example </p>
        <button onClick={startBarcodeScanner}> Scan Barcodes </button>
    </div>
);

Next, let’s create a scanResult state.

We can then set the value of scanResult within our startBarcodeScanner function when the scanning results are returned. Finally we can display those results below our button.

Our page.tsx should now look like this:

"use client";

import { useEffect, useState } from "react";
import type ScanbotSDK from "scanbot-web-sdk/UI";

export default function Home() {

  const [scanResult, setScanResult] = useState("");
  let ScanbotSdk: typeof ScanbotSDK;

  // initialize the Scanbot Barcode SDK
  useEffect(() => {
    loadSDK();
  });

  async function loadSDK() {
    // Use dynamic inline imports to load the SDK, else Next will load it into the server bundle
    // and attempt to load it before the 'window' object becomes available.
    // https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading
    ScanbotSdk = (await import('scanbot-web-sdk/UI')).default;

    await ScanbotSdk.initialize({
      licenseKey: "",
      enginePath: "/wasm/",
    });
  }

  async function startBarcodeScanner() {
    const config = new ScanbotSdk.UI.Config.BarcodeScannerScreenConfiguration();
    const result = await ScanbotSdk.UI.createBarcodeScanner(config);

    if (result && result.items.length > 0) {
      setScanResult(result.items[0].barcode.text);
    }
  }

  return (
    <div>
      <p>Scanbot Next.js Example</p>
      <button onClick={startBarcodeScanner}>Scan Barcodes</button>
      <p>{scanResult}</p>
    </div>
  );
}

With this setup, we now have a fully functional barcode scanner!

If you haven’t already, go to the local server running your app and click the “Scan Barcodes” button to open the scanner and scan a barcode. After scanning a barcode, the scanner will automatically close and the result variable in the startBarcodeScanner function will now contain the scan result, which will be displayed under the button.

💡 To test your Next.js project on your phone, you have a few options. One option for doing this is to use a service like ngrok, which creates a tunnel to one of their SSL-certified domains. Their Quick Start guide will help you get up and running quickly.

Scanning a single barcode with our Next.js barcode scanner

💡 If the icons for turning on the flashlight and switching cameras appear smaller than they should be or the buttons don’t behave as they should, copy this into src/app/global.css:

svg {
  padding: 0 !important;
}

If that doesn’t fix the issue, consider disabling Tailwind Preflight.

Optional: Customize the barcode scanner

The Scanbot SDK’s Ready-To-Use UI allows the user to customize several visual aspects of the RTU UI components, including its color palette, the user guidance, the top bar, and the action bar.

All the customization is done the same way: by changing values within the config object, within our startBarcodeScanner function, before passing it to ScanbotSdk.UI.createBarcodeScanner(config).

Color palette

Let’s start by changing the primary and secondary colors of the scanner to give it a blue theme.

config.palette.sbColorPrimary = "#1E90FF";
config.palette.sbColorSecondary = "#87CEEB";

User guidance

Next, we’ll change the text of the user guidance:

config.userGuidance.title.text = "Place the finder over the barcode";

Top bar

Let’s also change the top bar’s visual mode. We have the options of 'SOLID', 'GRADIENT', or 'HIDDEN'. We’ll use 'GRADIENT' for our example.

config.topBar.mode = "GRADIENT";

Action bar

Lastly, we have the option of changing the three action bar buttons that appear at the bottom of the screen: the Flash, Zoom and Flip Camera buttons. Let’s change the background color of our zoom button to match our blue theme.

config.actionBar.zoomButton.backgroundColor = "#1E90FF";

After adding these customization options, our startBarcodeScanner function should now look like this:

async function startBarcodeScanner() {
  const config = new ScanbotSdk.UI.Config.BarcodeScannerScreenConfiguration();

  config.palette.sbColorPrimary = "#1E90FF";
  config.palette.sbColorSecondary = "#87CEEB";

  config.userGuidance.title.text = "Place the finder over the barcode";

  config.topBar.mode = "GRADIENT";

  config.actionBar.zoomButton.backgroundColor = "#1E90FF";

  const result = await ScanbotSdk.UI.createBarcodeScanner(config);

  if (result && result.items.length > 0) {
    setScanResult(result.items[0].barcode.text);
  }
};

This only demonstrates a fraction of the available customization options for the RTU components. Please refer to our RTU UI documentation for more details and to the API documentation for a list of all available options.

Our Next.js barcode scanner after customizing its looks

Step 4: Implement additional scanning modes

The Scanbot Web Barcode Scanner SDK’s RTU UI also lets us modify the behavior of the scanner itself. So, rather than immediately closing the scanner after scanning a barcode, we can visualize the results in a variety of ways.

Let’s try out multi-barcode scanning combined with an AR overlay.

Multi-barcode scanning

Let’s create our useCase object to pass to our config.

const useCase = new ScanbotSdk.UI.Config.MultipleScanningMode();
config.useCase = useCase;

Now our scanner will have a collapsed list containing all scanned barcodes.

AR overlay

To enable the AR overlay, all we need to do is set the visibility to true within our use case configuration.

Let’s also disable the automatic selection, so we can manually select individual barcodes and add them to our list.

useCase.arOverlay.visible = true;
useCase.arOverlay.automaticSelectionEnabled = false;

Your startBarcodeScanner function (without the UI customizations) should now look something like this:

async function startBarcodeScanner() {
  const config = new ScanbotSdk.UI.Config.BarcodeScannerScreenConfiguration();

  const useCase = new ScanbotSdk.UI.Config.MultipleScanningMode();
  useCase.arOverlay.visible = true;
  useCase.arOverlay.automaticSelectionEnabled = false;
  config.useCase = useCase;

  const result = await ScanbotSdk.UI.createBarcodeScanner(config);

  if (result && result.items.length > 0) {
    // The scan result can contain several barcodes, but we're accessing the first one for simplicity's sake.
    setScanResult(result.items[0].barcode.text);
  }
}

🎉 Congratulations! You can now scan barcodes from your browser and adapt the scanner’s interface to suit your preferences.

Scanning multiple barcodes with our Next.js barcode scanner

These are just some of the customizations the Scanbot Web Barcode Scanner SDK has to offer. Check out the RTU UI Documentation for further details and the API Documentation for all available options.

Should you have questions about this tutorial or run into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io.