How to Make Dynamic Web TWAIN Work with Polymer Shadow DOM

In the past, Dynamic Web TWAIN only supported HTML DOM elements. Some web frameworks based on Shadow DOM, like Polymer, could not work with Dynamic Web TWAIN. Starting from version 16.1, Dynamic Web TWAIN was fully compatible with Shadow DOM. This article shares how to integrate Dynamic Web TWAIN SDK into a Polymer project for scanning documents in web browsers.

Dynamic Web TWAIN Quick Start

  1. Download Dynamic Web TWAIN SDK.

  2. Copy the Dynamic Web TWAIN SDK\Resources folder to your project root directory.

  3. Create an HTML file and get the full sample code from GitHub:

<!DOCTYPE html>
    <title>Hello World</title>
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"></script>
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"></script>
    <div id="dwtcontrolContainer" ></div>
    <input type="button" value="Scan" onclick="AcquireImage();" />
    <script type="text/javascript">
        Dynamsoft.WebTwainEnv.ProductKey = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
        function AcquireImage() {
          var DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');
          if (DWObject) {		
            DWObject.SelectSource(function () {		
              var OnAcquireImageSuccess = OnAcquireImageFailure = function () {
              DWObject.IfDisableSourceAfterAcquire = true;
              DWObject.AcquireImage(OnAcquireImageSuccess, OnAcquireImageFailure);
                      }, function () {
              console.log('SelectSource failed!');

With such a few steps, a simple web document management app is done. Without a web server, we can instantly run the web document scanner app by double-clicking the HTML file.

web document scan

A valid license key is required to make the app work. Get a 30-day FREE Trial License and update the code:

Dynamsoft.WebTwainEnv.ProductKey = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";

A Polymer Project for Scanning Documents

Install the Polymer CLI:

npm i -g polymer-cli

After that, we can initialize the Polymer project with a template:

mkdir polymer-document-scan
cd polymer-document-scan
polymer init polymer-3-starter-kit
npm start

Polymer project

Integrating Dynamic Web TWAIN into Polymer Project

Now, let’s modify the default UI by adding a Div element and a Button element to the HTML template in src/my-view.js:

class MyView1 extends PolymerElement {
  static get template() {
    return html`
      <style include="shared-styles">
        :host {
          display: block;
          padding: 10px;
      <div class="card">
      <div id="dwtcontrolContainer"></div>
      <button on-click="handleClick">scan</button>
  handleClick() {
    if (DWObject) {

Add scan module to Polymer project

It will fail to initialize Dynamic Web TWAIN object if we use the code of ‘Hello World’ sample:

var DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');

The reason is the element cannot be found. To investigate the issue, open the developer console.

Shadow DOM

The developer console shows the Div element is a child of shadow DOM. Here is the JS code to get the Shadow DOM element:

document.querySelector("body > my-app").shadowRoot.querySelector("app-drawer-layout > app-header-layout > iron-pages > my-view1").shadowRoot.querySelector("#dwtcontrolContainer")

Don’t panic. The code could be simplified as follows:


Since Dynamic Web TWAIN has supported Shadow DOM, we can easily initialize Dynamic Web TWAIN object with a Shadow DOM element by using the bind() method:

ready() {
    // TODO: initialization

  initializeDWT() {
    // Dynamsoft.WebTwainEnv.ProductKey = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
    Dynamsoft.WebTwainEnv.CreateDWTObjectEx({ WebTwainId: 'Viewer' }, (obj) => {
      this.dwtObj = obj;
      obj.Viewer.width = 560;
      obj.Viewer.height = 600;;

      var count = obj.SourceCount;
      for (var i = 0; i < count; i++) {
        this.shadowRoot.querySelector('#source').options.add(new Option(obj.GetSourceNameItems(i), i));

    }, function (e) {

We create a click event for triggering document scanning.

handleClick() {
    var obj = this.dwtObj;
    if (obj) {
      var onSuccess, onFailure;
      onSuccess = onFailure = function () {

      obj.IfDisableSourceAfterAcquire = true;	
      obj.AcquireImage(onSuccess, onFailure);

Finally, the web document scan app implemented in Polymer can work successfully.

Polymer Shadow DOM document scan

Source Code