{"id":29075188,"url":"https://github.com/dynamsoft/document-scanner-javascript","last_synced_at":"2026-01-20T16:40:22.523Z","repository":{"id":274543141,"uuid":"914967779","full_name":"Dynamsoft/document-scanner-javascript","owner":"Dynamsoft","description":"Add document scanning to web apps with real-time capture, edge detection, and image enhancement. Lightweight and customizable.","archived":false,"fork":false,"pushed_at":"2025-05-01T21:21:40.000Z","size":972,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-01T16:42:50.877Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dynamsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-10T17:20:21.000Z","updated_at":"2025-05-01T21:21:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"cde5d97c-2e4e-43cd-83f2-db288d0c2122","html_url":"https://github.com/Dynamsoft/document-scanner-javascript","commit_stats":null,"previous_names":["dynamsoft/document-scanner-javascript"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Dynamsoft/document-scanner-javascript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynamsoft%2Fdocument-scanner-javascript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynamsoft%2Fdocument-scanner-javascript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynamsoft%2Fdocument-scanner-javascript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynamsoft%2Fdocument-scanner-javascript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dynamsoft","download_url":"https://codeload.github.com/Dynamsoft/document-scanner-javascript/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynamsoft%2Fdocument-scanner-javascript/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262279298,"owners_count":23286554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-27T15:10:26.926Z","updated_at":"2026-01-20T16:40:22.513Z","avatar_url":"https://github.com/Dynamsoft.png","language":"TypeScript","readme":"# Scan Documents with Mobile Document Scanner\n\nDynamsoft's **Mobile Document Scanner JavaScript Edition (MDS)** is a web SDK designed for scanning documents. MDS captures images of the documents and enhances their quality to professional standards, making it an ideal tool for mobile document scanning.\n\n\u003e See it in action with the [Mobile Document Scanner Demo](https://demo.dynamsoft.com/document-scanner/).\n\n**Table of Contents**\n\n\u003c!--toc:start--\u003e\n\n- [Scan Documents with Mobile Document Scanner](#scan-documents-with-mobile-document-scanner)\n  - [License](#license)\n    - [Get a Trial License](#get-a-trial-license)\n    - [Get a Full License](#get-a-full-license)\n  - [Quick Start](#quick-start)\n    - [Build from Source](#build-from-source)\n    - [Use Precompiled Script](#use-precompiled-script)\n    - [Self-Host Resources](#self-host-resources)\n      - [Download Resources](#download-resources)\n      - [Point to Resources](#point-to-resources)\n      - [Modify the Build Script](#modify-the-build-script)\n      - [Build the Project](#build-the-project)\n      - [Serve the Project Locally](#serve-the-project-locally)\n      - [Serve over HTTPS](#serve-over-https)\n      - [Set MIME Type](#set-mime-type)\n      - [Resource Caching](#resource-caching)\n  - [Hello World Sample Explained](#hello-world-sample-explained)\n    - [Reference MDS](#reference-mds)\n    - [Instantiate MDS](#instantiate-mds)\n    - [Launch MDS](#launch-mds)\n    - [Display the Result](#display-the-result)\n  - [Custom Usage](#custom-usage)\n    - [`DocumentScannerConfig` Overview](#documentscannerconfig-overview)\n    - [Multi-Page Scanning](#multi-page-scanning)\n      - [Basic Multi-Page Scanning](#basic-multi-page-scanning)\n        - [Explanation](#explanation)\n        - [Optional Settings](#optional-settings)\n      - [Multi-Page Scanning with DDV](#multi-page-scanning-with-ddv)\n        - [Explanation](#explanation-1)\n    - [Workflow Customization](#workflow-customization)\n      - [Example 1: Confine DocumentScanner UI to a Specific Container](#example-1-confine-documentscanner-ui-to-a-specific-container)\n      - [Example 2: Only Show `DocumentScannerView`](#example-2-only-show-documentscannerview)\n      - [Example 3: Specify Individual View Containers](#example-3-specify-individual-view-containers)\n      - [Example 4: Scan Static Image Directly](#example-4-scan-static-image-directly)\n      - [Example 5: Configure Scan Modes](#example-5-configure-scan-modes)\n    - [View-Based Customization](#view-based-customization)\n      - [`DocumentScannerView` Configuration](#documentscannerview-configuration)\n        - [Customizing the `DocumentScannerView` UI](#customizing-the-documentscannerview-ui)\n        - [Steps to Customize the UI for `DocumentScannerView`](#steps-to-customize-the-ui-for-documentscannerview)\n        - [Customizing the Scanning Region](#customizing-the-scanning-region)\n      - [`DocumentCorrectionView` Configuration](#documentcorrectionview-configuration)\n        - [Styling `DocumentCorrectionView` Buttons](#styling-documentcorrectionview-buttons)\n        - [Customizing Apply Button Callback](#customizing-apply-button-callback)\n      - [`DocumentResultView` Configuration](#documentresultview-configuration)\n        - [Styling `DocumentResultView` Buttons](#styling-documentresultview-buttons)\n        - [Customizing the \"Done\" Button Callback](#customizing-the-done-button-callback)\n        - [Customizing the \"Upload\" Button](#customizing-the-upload-button)\n  - [Next Step](#next-step)\n  \u003c!--toc:end--\u003e\n\n## License\n\n### Get a Trial License\n\nTry **MDS** by requesting a trial license through our [customer portal](https://www.dynamsoft.com/customer/license/trialLicense?product=mwc\u0026source=guide). The trial can be renewed twice, providing a total of two months of free access.\n\n### Get a Full License\n\nTo purchase a full license, [contact us](https://www.dynamsoft.com/company/contact/).\n\n## Quick Start\n\nThe following section explains how to quickly run a simple, single-page web application to scan **single page documents**. See the [**multi-page scanning guide**](#multi-page-scanning) to scan multi-page documents.\n\nTo use the **Mobile Document Scanner**, first obtain its library files. You can acquire them from one of the following sources:\n\n1. [**GitHub**](https://github.com/Dynamsoft/document-scanner-javascript) – contains the source files for the **MDS** SDK, which can be compiled into library files.\n2. [**npm**](https://www.npmjs.com/package/dynamsoft-document-scanner) – provides precompiled library files via npm for easier installation.\n3. [**CDN**](https://www.jsdelivr.com/package/npm/dynamsoft-document-scanner) – delivers precompiled library files through a CDN for quick and seamless integration.\n\nYou can choose one of the following methods to set up a Hello World page:\n\n1. **Build from source** – download the source files from GitHub and compile the library files yourself.\n2. **Use precompiled scripts** – use the precompiled resource scripts from npm or the CDN for a quicker setup.\n3. **Self-host resources** - self-host both MDS and its dependencies on your web server.\n\n### Build from Source\n\nThis method retrieves all **MDS** source files from its [GitHub Repository](https://github.com/Dynamsoft/document-scanner-javascript), compiles them into a distributable package, and then runs a _ready-made_ Hello World sample page included in the repository:\n\n1. Download **MDS** from [GitHub](https://github.com/Dynamsoft/document-scanner-javascript) as a compressed folder.\n\n2. Extract the contents of the archive, and open the extracted directory in a code editor.\n\n3. Set your [license key](#get-a-trial-license) in the Hello World sample:\n\n   1. Open the Hello World sample at [`/samples/hello-world.html`](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/samples/hello-world.html).\n   2. Search for `\"YOUR_LICENSE_KEY_HERE\"`, then replace it with your actual license key.\n\n4. In the terminal, navigate to the project root directory and run the following to install project dependencies:\n\n   ```shell\n   npm install\n   ```\n\n5. After installing dependencies, build the project by running:\n\n   ```shell\n   npm run build\n   ```\n\n6. Start the local server by running the following to serve the project locally:\n\n   ```shell\n   npm run serve\n   ```\n\n   Once the server is running, open the application in a browser using the address provided in the terminal output after running `npm run serve`.\n\n   \u003e See the server configuration details in [`/dev-server/index.js`](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/dev-server/index.js).\n\n### Use Precompiled Script\n\nWe publish **MDS** library files on [npm](https://www.npmjs.com/package/dynamsoft-document-scanner) to make them simple to reference from a CDN.\n\nTo use the precompiled script, simply include the following URL in a `\u003cscript\u003e` tag:\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/dynamsoft-document-scanner@1.4.0/dist/dds.bundle.js\"\u003e\u003c/script\u003e\n```\n\nBelow is the complete Hello World sample page that uses this precompiled script from a CDN.\n\n\u003e The code is identical to the [`/samples/hello-world.html`](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/samples/hello-world.html) file mentioned in the [Build from Source](#build-from-source) section, except for the script source.\n\n\u003e **Remember** to replace `\"YOUR_LICENSE_KEY_HERE\"` with your actual license key.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e\n    \u003ctitle\u003eMobile Document Scanner - Hello World\u003c/title\u003e\n    \u003cscript src=\"https://cdn.jsdelivr.net/npm/dynamsoft-document-scanner@1.4.0/dist/dds.bundle.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003ch1 style=\"font-size: large\"\u003eMobile Document Scanner\u003c/h1\u003e\n    \u003cdiv id=\"results\"\u003e\u003c/div\u003e\n    \u003cscript\u003e\n      const resultContainer = document.querySelector(\"#results\");\n      // Instantiate a Document Scanner Object\n      const documentScanner = new Dynamsoft.DocumentScanner({\n        license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n      });\n      (async () =\u003e {\n        // Launch the scanner and wait for the result\n        const result = await documentScanner.launch();\n        console.log(result);\n\n        // Clear the result container and display the scanned result as a canvas\n        if (result?.correctedImageResult) {\n          resultContainer.innerHTML = \"\"; // Clear placeholder content\n          const canvas = result.correctedImageResult.toCanvas();\n          resultContainer.appendChild(canvas);\n        } else {\n          resultContainer.innerHTML = \"\u003cp\u003eNo image scanned. Please try again.\u003c/p\u003e\";\n        }\n      })();\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nTo run the sample, create a new file called `hello-world.html`, then copy and paste the code above into the file. Next, serve the page directly by deploying it to a server.\n\nIf you are using VS Code, a quick and easy way to serve the project is using the [Live Server (Five Server) VSCode extension](https://marketplace.visualstudio.com/items?itemName=yandeu.five-server). Simply install the extension, open the `hello-world.html` file in the editor, and click \"Go Live\" in the bottom right corner of the editor. This will serve the application at `http://127.0.0.1:5500/hello-world.html`.\n\nAlternatively, you can use other methods like `IIS` or `Apache` to serve the project, though we skip those here for brevity.\n\n### Self-Host Resources\n\nBy default, the MDS library (whether pre-compiled or self-compiled) fetches resource files (Dynamsoft `node` dependencies and an HTML UI template) from CDNs. Self-hosting library resources gives you full control over hosting your application. Rather than using CDNs to serve these resources, you can instead host these resources on your own servers to deliver to your users directly when they use your application. You can also use this option to host MDS fully offline by pointing to local resources.\n\n#### Download Resources\n\nFirst, download a copy of the resources:\n\n1. Download **MDS** from [GitHub](https://github.com/Dynamsoft/document-scanner-javascript) as a compressed folder.\n\n2. Extract the contents of the archive, and open the extracted directory in a code editor.\n\n3. Set your [license key](#get-a-trial-license) in the Hello World sample:\n\n   1. Open the Hello World sample at ([`/samples/hello-world.html`](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/samples/hello-world.html)).\n\n   2. Search for `\"YOUR_LICENSE_KEY_HERE\"`, then replace it with your actual license key.\n\n4. In the terminal, navigate to the project root directory and run the following to install project dependencies:\n\n   ```shell\n   npm install\n   ```\n\n#### Point to Resources\n\nThe library uses [`engineResourcePaths`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#engineresourcepaths) to locate required Dynamsoft `node` dependencies by pointing to the location of the resources on your web server. The library also uses `scannerViewConfig.cameraEnhancerUIPath` similarly to set the path for the HTML UI template of the `ScannerView`. Later steps will place both the `node` dependencies and the HTML template in the local `dist` directory. Therefore, set `engineResourcePaths` in the MDS constructor to point to the local `dist` directory (along with setting your license key, and all other configurations):\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\",\n  scannerViewConfig: {\n    cameraEnhancerUIPath: \"./dist/document-scanner.ui.xml\", // Use the local file\n  },\n  engineResourcePaths: {\n    std: \"./dist/libs/dynamsoft-capture-vision-std/dist/\",\n    dip: \"./dist/libs/dynamsoft-image-processing/dist/\",\n    core: \"./dist/libs/dynamsoft-core/dist/\",\n    license: \"./dist/libs/dynamsoft-license/dist/\",\n    cvr: \"./dist/libs/dynamsoft-capture-vision-router/dist/\",\n    ddn: \"./dist/libs/dynamsoft-document-normalizer/dist/\",\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentScannerViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerviewconfig)\n- [`engineResourcePaths`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#engineresourcepaths)\n- [`cameraEnhancerUIPath`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#cameraenhanceruipaths)\n\n#### Modify the Build Script\n\nUpdate the `scripts` section in `package.json` to automatically copy resources to the output `dist` directory during the build process.\n\n```json\n\"scripts\": {\n    \"serve\": \"node dev-server/index.js\",\n    \"build\": \"rollup -c \u0026\u0026 npm run copy-libs\",\n    \"copy-libs\": \"npx mkdirp dist/libs \u0026\u0026 npx cpx \\\"node_modules/dynamsoft-*/**/*\\\" dist/libs/ --dereference\",\n    \"build:production\": \"rollup -c --environment BUILD:production\"\n},\n```\n\n#### Build the Project\n\nBuild the project by running:\n\n```shell\nnpm run build\n```\n\n#### Serve the Project Locally\n\nStart the local development server by running:\n\n```shell\nnpm run serve\n```\n\nOnce the server is running, open the application in a browser using the address provided in the terminal output.\n\n#### Serve over HTTPS\n\n**Place the `dist` directory** onto your web server to serve the web application. When deploying your web application for production, you must serve it over a **secure HTTPS connection**. We require this for the following reasons:\n\n1. **Browser Security Restrictions** – Most browsers only allow access to camera video streams in a secure context.\n\n   \u003e Some browsers like Chrome may grant access to camera video streams for `http://127.0.0.1`, `http://localhost`, or even pages opened directly from the local file system (`file:///...`). This can be helpful during development and testing.\n\n2. **Dynamsoft License Requirements** – A secure context is required for **Dynamsoft licenses** to function properly.\n\n#### Set MIME Type\n\nCertain legacy web application servers may lack support for the `application/wasm` mimetype for .wasm files. To address this, you have two options:\n\n1. Upgrade your web application server to one that supports the `application/wasm` mimetype.\n2. Manually define the mimetype on your server by setting the MIME type for `.wasm` as `application/wasm`. This allows the user's browser to correctly process resource files. Different web servers have their own way of configuring the MIME type. Here are instructions for [Apache](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Apache_Configuration_htaccess#media_types_and_character_encodings), [IIS](https://docs.microsoft.com/en-us/iis/configuration/system.webserver/staticcontent/mimemap), and [NGINX](https://www.nginx.com/resources/wiki/start/topics/examples/full/#mime-types).\n\n#### Resource Caching\n\nThe `wasm` resource files are relatively large and may take quite a few seconds to download. We recommend setting a longer cache time for these resource files to maximize the performance of your web application using the `Cache-Control` HTTP header. For example, use the `max-age` directive to cache resources for a specified time in seconds:\n\n```\nCache-Control: max-age=31536000\n```\n\nReference:\n[`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)\n\n## Hello World Sample Explained\n\nHere we walk through the code in the Hello World sample to explain its function and usage.\n\n\u003e You can also view the full code by visiting the [MDS JS Hello World Sample on Github](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/samples/hello-world.html).\n\n### Reference MDS\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e\n    \u003ctitle\u003eMobile Document Scanner - Hello World\u003c/title\u003e\n    \u003cscript src=\"../dist/dds.bundle.js\"\u003e\u003c/script\u003e\n    \u003c!--Alternatively, reference the script from CDN\n    \u003cscript src=\"https://cdn.jsdelivr.net/npm/dynamsoft-document-scanner@1.4.0/dist/dds.bundle.js\"\u003e\u003c/script\u003e\n    --\u003e\n  \u003c/head\u003e\n\u003c/html\u003e\n```\n\nIn this step, we reference MDS with a relative path to the local file in the `\u003chead\u003e` section of the HTML.\n\n```html\n\u003cscript src=\"../dist/dds.bundle.js\"\u003e\u003c/script\u003e\n```\n\nAlternatively, you can reference the script hosted on a CDN, for example, on JSDelivr:\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/dynamsoft-document-scanner@1.4.0/dist/dds.bundle.js\"\u003e\u003c/script\u003e\n```\n\n**MDS** wraps all its dependency scripts, so a **MDS** project only needs to include **MDS** itself as a single script. No additional dependency scripts are required.\n\n\u003e Even if you reference the script itself locally, MDS still defaults to loading supporting resources like `.wasm` engine files from the CDN at runtime. If you require a **fully offline setup**, follow the [quick start instructions to self-host resources](#quick-start).\n\n### Instantiate MDS\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n});\n```\n\nAPI Reference: [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n\nThis step creates the **MDS** UI, which by default occupies the entire visible area of the browser window when launched. If needed, you can restrict the UI to a specific container. For more details, refer to [Confine DocumentScanner UI to a Specific Container](#example-1-confine-documentscanner-ui-to-a-specific-container).\n\n\u003e Instantiating the `DocumentScanner` requires a valid license key.\n\n### Launch MDS\n\n```javascript\nconst result = await documentScanner.launch();\n```\n\nAPI Reference:\n\n- [`launch()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#launch)\n\nThis step launches the user into the document scanning workflow, beginning in the `DocumentScannerView`, where they can scan a document using one of three methods:\n\n- Option 1: Manually scan by pressing the **shutter button**.\n- Option 2: Enable \"**Smart Capture**\" - the scanner will automatically capture an image once a document is detected.\n- Option 3: Enable \"**Auto Crop**\" - the scanner will automatically capture an image, detect the document, and crop it out of the video frame.\n\n\u003e For Options 1 \u0026 2: The user is directed to `DocumentCorrectionView` to review detected document boundaries and make any necessary adjustments before applying corrections. Afterward, they proceed to `DocumentResultView`.\n\u003e\n\u003e For Option 3: The `DocumentCorrectionView` step is skipped. Image correction is applied automatically, and the user is taken directly to `DocumentResultView`.\n\nIn `DocumentResultView`, if needed, the user can return to `DocumentCorrectionView` to make additional adjustments or press \"Re-take\" to restart the scanning process.\n\n### Display the Result\n\nThe workflow returns a scanned image object of type `CorrectedImageResult`. To display the scanned `result` image, we use a `\u003cdiv\u003e` in the `\u003cbody\u003e`:\n\n```html\n\u003cbody\u003e\n  \u003ch1 style=\"font-size: large\"\u003eMobile Document Scanner\u003c/h1\u003e\n  \u003cdiv id=\"results\"\u003e\u003c/div\u003e\n\u003c/body\u003e\n```\n\nAPI Reference:\n\n- [`DocumentResult`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentresult)\n\nThe following code clears the result container and displays the scanned result as a canvas:\n\n```javascript\nif (result?.correctedImageResult) {\n  resultContainer.innerHTML = \"\";\n  const canvas = result.correctedImageResult.toCanvas();\n  resultContainer.appendChild(canvas);\n} else {\n  resultContainer.innerHTML = \"\u003cp\u003eNo image scanned. Please try again.\u003c/p\u003e\";\n}\n```\n\n## Custom Usage\n\nThis section builds on the Hello World sample to demonstrate how to configure **MDS**, typically by adjusting the `DocumentScannerConfig` object.\n\n### `DocumentScannerConfig` Overview\n\n[`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig) is the primary configuration object for customizing **MDS**. It includes the following properties:\n\n1. `license` - the license key.\n2. `container` - the HTML container for the entire workflow. If not specified (like in the Hello World Sample), one is created automatically.\n3. `showCorrectionView` - toggle `DocumentCorrectionView` in the scanning workflow.\n4. `showResultView` - toggle `DocumentResultView` in the scanning workflow.\n5. `enableFrameVerification` - toggle selecting the clearest of multiple video frames upon scanning (on by default).\n6. `enableContinuousScanning` - toggle continuous scanning mode to make multiple scans on a single `launch()` (`false` by default).\n7. `onDocumentScanned` - handler to get single scan results in continuous scanning mode (if `enableContinuousScanning` is `true`).\n8. `stopContinuousScanning` - programmatically stop the scanning loop when continuous scanning mode is enabled.\n9. `scannerViewConfig` - configure the main scanner view with the following properties:\n   1. `container` - the HTML container for the `DocumentScannerView`.\n   2. `cameraEnhancerUIPath` - path to the UI definition file (.html) for the `DocumentScannerView`.\n   3. `enableAutoCropMode` - set the default value of Auto-Crop upon entering the `DocumentScannerView`.\n   4. `enableSmartCaptureMode` - set the default state of Smart Capture upon entering the `DocumentScannerView`.\n   5. `enableBoundsDetectionMode` - set the default state of bounds detection mode upon entering the `DocumentScannerView`.\n   6. `scanRegion` - set the scan region within the document scanning viewfinder.\n   7. `minVerifiedFramesForSmartCapture` - set the minimum number of video frames to verify detected document boundaries on Smart Capture mode. Higher frame counts lead to higher confidence at the cost of discarding results.\n   8. `showSubfooter` - toggle the visibility of the mode selector menu.\n   9. `showPoweredByDynamsoft` - set the visibility of the Dynamsoft branding message.\n10. `correctionViewConfig` - configure the `DocumentCorrectionView`.\n   1. `container` - the HTML container for the `DocumentCorrectionView`.\n   2. `toolbarButtonsConfig` - configure the appearance and labels of the buttons for the `DocumentCorrectionView` UI.\n   3. `onFinish` - handler called when the user clicks the \"Apply\" button.\n11. `resultViewConfig` - configure the result view with the following properties:\n   1. `container` - the HTML container for the `DocumentResultView`.\n   2. `toolbarButtonsConfig` - configure the appearance and labels of the buttons for the `DocumentResultView` UI.\n   3. `onDone` - handler called when the user clicks the \"Done\" button.\n   4. `onUpload` - handler called when the user clicks the \"Upload\" button.\n12. `templateFilePath` - path to a Capture Vision template for scanning configuration; typically not needed as the default template is used.\n13. `utilizedTemplateNames`- template names for detection and correction. Typically not needed as the default template is used.\n14. `engineResourcePaths` - paths to extra resources such as `.wasm` engine files.\n\nFurthermore, we explore three main (non-mutually-exclusive) avenues of customization with `DocumentScannerConfig`:\n\n1. [**Multi-Page Scanning](#multi-page-scanning): through configuration objects and container definitions.\n2. [**Workflow Customization**](#workflow-customization): through container definitions.\n3. [**View-Based Customization**](#view-based-customization): through configuration objects.\n\nThe customization examples below build on the Hello World code from the [previous section](#use-precompiled-script). The only change required is adjusting the constructor argument.\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  // Add more arguments\n});\n```\n\n### Multi-Page Scanning\n\nMobile Document Scanner can scan multi-page documents when configured to use the continuous scanning mode. Unlike the default behavior of returning a single scan on calling `launch()`, continuous scanning outputs a scan result on every successful scan, which you can further process by providing a handler. The workflow repeats to let the user scan through large documents efficiently.\n\nSee [**Workflow Customization**](#workflow-customization) and [**View-Based Customization**](#view-based-customization) for a more thorough explanation of the customization syntax.\n\n#### Basic Multi-Page Scanning\n\n[**Full Sample Source Code**](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/samples/scenarios/multi-page-scanning.html)\n\nThe most straightforward way to implement multi-page scanning is to enable continuous scanning mode and provide a callback handler to process each scanned document via [`onDocumentScanned`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#ondocumentscanned). The scanner loops after each successful scan, allowing users to capture multiple pages in succession. The user can manually stop scanning by clicking the \"Done\" or close buttons from the Document Scanner View. Consider the relevant sections from the source code below:\n\n```html\n\u003cdiv id=\"results\"\u003e\u003c/div\u003e\n```\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\",\n  enableContinuousScanning: true,\n  onDocumentScanned: (result) =\u003e {\n    // Process each scanned document\n    const canvas = result.correctedImageResult.toCanvas();\n    document.getElementById(\"results\").appendChild(canvas);\n  },\n});\n\nawait documentScanner.launch();\n```\n\nAPI Reference:\n\n- [`DocumentScannerConfig.enableContinuousScanning`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#enableContinuousScanning)\n- [`DocumentScannerConfig.onDocumentScanned`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#ondocumentscanned)\n\n##### Explanation\n\nThere are two essential components to multi-page scanning - enabling continuous scanning mode, and providing your handler to process the scanned pages.\n\n1. We enable continuous scanning with the [`enableContinuousScanning`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#enableContinuousScanning) property - this is responsible for changing the user workflow, automatically going back to the scanner view to take more scans after confirming each scan.\n2. We can then provide a handler to process the document pages to [`onDocumentScanned`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#ondocumentscanned). This handler gets called on confirming every scan. In this example, we simply display the result image to the page.\n\n\u003e [!NOTE]\n\u003e Just as in single-scan mode, `launch()` returns a `DocumentResult` promise. In continuous scanning mode, `launch()` returns a **`DocumentResult` promise to the last page scanned**.\n\n##### Optional Settings\n\nTo enhance the scanning process, you may also choose to use the following settings:\n\n1. Provide a handler to [`onThumbnailClicked`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#onthumbnailclicked), for example, to show a full preview of the last scanned page.\n2. Stop the scanning loop programmatically by calling [`stopContinuousScanning()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#stopcontinuousscanning) externally. This is particularly useful if scanning a pre-determined number of pages by counting the number of scans received by `onThumbnailClicked`.\n3. For a faster scanning experience, enable both Smart Capture and Auto-Crop modes by default without requiring the user to re-enable them for each scan. See [Configure Scan Modes](#example-5-configure-scan-modes) for details.\n4. Under certain use cases where the user does not need to manually edit or change the document boundaries, you can also skip the Document Correction and Document Result Views entirely. This allows the user to stay within the Document Scanner View to capture with the least number of manual interactions per scan. See [Only Show `DocumentScannerView`](#example-2-only-show-documentscannerview) for details.\n\n#### Multi-Page Scanning with DDV\n\n\u003e [!TIP]\n\u003e You can find the full set of comprehensive documentation Dynamsoft Document Viewer [on our website](https://www.dynamsoft.com/document-viewer/docs/introduction/index.html).\n\n[**Full Sample Source Code**](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/samples/scenarios/scanning-to-pdf.html)\n\nFor a more advanced multi-page scanning solution with document management, image editing, and comprehensive file support capabilities (including PDF), you can integrate **MDS** with **Dynamsoft Document Viewer (DDV)**. This combination provides:\n\n- Document editing and management\n- Thumbnail previews\n- Page reordering and deletion\n- PDF export functionality\n- A polished UI for both mobile and desktop\n\nGiven the length of the sample, we only provide a snippet for creating the MDS instance here. See the full sample for more. Please see the [DDV documentation](https://www.dynamsoft.com/document-viewer/docs/introduction/index.html) for DDV-related APIs.\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  // Public trial license which is valid for 24 hours\n  // You can request a 30-day trial key from https://www.dynamsoft.com/customer/license/trialLicense/?product=mds\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  container: scannerContainer,\n  scannerViewConfig: {\n    enableAutoCropMode: true,\n    enableSmartCaptureMode: true,\n  },\n  enableContinuousScanning: true,\n  onDocumentScanned: async (result) =\u003e {\n    try {\n      // Convert the scanned image to blob\n      const canvas = result.correctedImageResult.toCanvas();\n      const blob = await new Promise((resolve) =\u003e {\n        canvas.toBlob((b) =\u003e resolve(b), \"image/jpeg\", 0.9);\n      });\n\n      // Add the scanned page to DDV document\n      if (blob) {\n        await doc.loadSource([\n          {\n            convertMode: \"cm/auto\",\n            fileData: blob,\n          },\n        ]);\n      }\n    } catch (error) {\n      console.error(\"Error adding scanned page to DDV:\", error);\n    }\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScannerViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerviewconfig)\n- [`enableAutoCropMode`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#enableautocropmode)\n- [`enableSmartCaptureMode`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#enablesmartcapturemode)\n- [`DocumentScannerConfig.enableContinuousScanning`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#enableContinuousScanning)\n- [`onDocumentScanned`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#ondocumentscanned)\n- [`loadsource()`](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/index.html#loadsource)\n\n##### Explanation\n\nFor brevity, we outline the key steps in this sample implementation:\n\n1. Initialize DDV\n2. Customize the DDV edit viewer (notably by adding a scan button that launches MDS)\n3. Instantiate the DDV edit viewer\n4. Create a DDV document\n5. Create a `DocumentScanner` instance\n  1. Enable continuous scanning\n  2. On confirming a scan, convert and send the image to the DDV document with [`loadsource()`](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/index.html#loadsource) in the MDS event handler\n6. Add an event to launch MDS from clicking the custom scan button added to ddv\n7. Add an event to DDV that outputs a PDF of the scanned documents from DDV on close using [`saveToPdf()`](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/#savetopdf)\n\n### Workflow Customization\n\nIn the Hello World sample, we use the complete workflow with minimum configuration:\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n});\n// Launch the scanner and wait for the result\nconst result = await documentScanner.launch();\n```\n\nIn this case, **MDS** automatically creates container elements for its **Views**. In this section we discuss a few ways to adjust the **MDS** workflow.\n\n#### Example 1: Confine DocumentScanner UI to a Specific Container\n\nAs long as the `DocumentScanner` container is assigned, **MDS** confines its **Views** within that container.\n\n\u003e Containers assigned to its constituent **Views** will be ignored.\n\n```html\n\u003cdiv id=\"myDocumentScannerContainer\" style=\"width: 80vw; height: 80vh;\"\u003e\u003c/div\u003e\n```\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  container: document.getElementById(\"myDocumentScannerContainer\"), // Use this container for the full workflow\n  scannerViewConfig: {\n    container: document.getElementById(\"myDocumentScannerViewContainer\"), // This container is ignored\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n\n#### Example 2: Only Show `DocumentScannerView`\n\nIf you do not need either the `DocumentResultView` or `DocumentCorrectionView` in your workflow (for example, if you do not want your user to manually alter the detected document boundaries), you can hide the views with the following configuration properties like so:\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  showResultView: false,\n  showCorrectionView: false,\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n\n#### Example 3: Specify Individual View Containers\n\nIf the configuration object provide containers for the `DocumentScannerView`, `DocumentResultView`, and `DocumentCorrectionView`, but **does not provide** the `DocumentScanner` container, then **MDS** renders the full workflow using these three containers.\n\n```html\n\u003cdiv id=\"myDocumentScannerViewContainer\" style=\"width: 80vw; height: 80vh\"\u003e\u003c/div\u003e\n\u003cdiv id=\"myDocumentCorrectionViewContainer\" style=\"width: 80vw; height: 80vh\"\u003e\u003c/div\u003e\n\u003cdiv id=\"myScanResultViewContainer\" style=\"width: 80vw; height: 80vh\"\u003e\u003c/div\u003e\n```\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  scannerViewConfig: {\n    container: document.getElementById(\"myDocumentScannerViewContainer\"),\n  },\n  correctionViewConfig: {\n    container: document.getElementById(\"myDocumentCorrectionViewContainer\"),\n  },\n  resultViewConfig: {\n    container: document.getElementById(\"myScanResultViewContainer\"),\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n\n#### Example 4: Scan Static Image Directly\n\nTo scan an image file directly without displaying the `DocumentScannerView` UI at all, you can pass a `File` object to `launch()`. As an example, select an image file from the local disk:\n\n```html\n\u003cinput type=\"file\" id=\"initialFile\" accept=\"image/png,image/jpeg\" /\u003e\n```\n\nThen get the input file as a `File` object, and pass that file object to `launch()` MDS with:\n\n```javascript\ndocument.getElementById(\"initialFile\").onchange = async function () {\n  const files = Array.from(this.files || []);\n  if (files.length) {\n    const result = await documentScanner.launch(files[0]);\n    console.log(result);\n\n    // Clear the result container and display the scanned result as a canvas\n    if (result?.correctedImageResult) {\n      resultContainer.innerHTML = \"\"; // Clear placeholder content\n      const canvas = result.correctedImageResult.toCanvas();\n      resultContainer.appendChild(canvas);\n    } else {\n      resultContainer.innerHTML = \"\u003cp\u003eNo image scanned. Please try again.\u003c/p\u003e\";\n    }\n  }\n};\n```\n\nThis hides the `DocumentScannerView` UI entirely and brings up the `DocumentCorrectionView` as the first view, after having detected document boundaries on the static image. The user can proceed through the rest of the workflow and further alter the document boundaries, re-take another image (to open up the `DocumentScannerView`), etc.\n\n\u003e `launch()` can accept images or PDFs. If launching with a PDF, MDS will **only process the first page**.\n\n\u003e You can completely disable all UI and use MDS to scan a file completely statically by hiding both the `DocumentCorrectionView` and the `DocumentResultView` in [example 2](#example-2-only-show-documentscannerview).\n\n#### Example 5: Configure Scan Modes\n\nThe Document Scanner View comes with three scan modes:\n\n1. Border Detection\n2. Auto-Crop\n3. Smart Capture\n\nBy default, Border Detection mode is enabled upon entering the Scanner View, while the other two are turned off by default. The user can then enable them by clicking their respective icons in the scanning mode sub-footer. From the `DocumentScannerViewConfig` interface, you can:\n\n1. Set the default state of Auto-Crop mode with `enableAutoCropMode`\n2. Set the default state of Smart Capture mode with `enableSmartCaptureMode`\n3. Set the visibility of the scanning mode sub-footer with `showSubfooter`\n\n\u003e Border Detection Mode is always enabled upon the Scanner View, and the scanning sub-footer is visible by default.\n\nFor example, the following config enables all three scanning modes and hides the scanning mode sub-footer to prevent the viewer from changing or viewing the scanning modes:\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  scannerViewConfig: {\n    enableAutoCropMode: true,\n    enableSmartCaptureMode: true,\n    showSubfooter: false,\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentScannerViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerviewconfig)\n\n### View-Based Customization\n\nIn addition to modifying the workflow, you can customize individual Views with configuration options for UI styling, button settings, and event handling.\n\n#### `DocumentScannerView` Configuration\n\n##### Customizing the `DocumentScannerView` UI\n\nYou can extensively customize the `DocumentScannerView` by editing its HTML template. Consider the following properties of the `DocumentScannerViewConfig` used for customizing the `DocumentScannerView`:\n\n```typescript\ninterface DocumentScannerViewConfig {\n  container?: HTMLElement;\n  templateFilePath?: string;\n  cameraEnhancerUIPath?: string;\n}\n```\n\nOf these three properties, we focus on `cameraEnhancerUIPath`. Here we omit `container`, as we cover it in [Workflow Customization](#workflow-customization), and we omit `templateFilePath`, as it refers to the DCV template file that configures document boundary detection algorithms.\n\n\u003e If the performance of **MDS** does not meet your needs, you may require an algorithm template **customized for your usage scenario** for better results. Please contact our experienced [Technical Support Team](https://www.dynamsoft.com/company/contact/) to discuss your requirements. We can tailor a suitable template for you, which you can then apply by updating `templateFilePath`.\n\n`cameraEnhancerUIPath` points to a file hosted on the jsDelivr CDN by default (see [Self-Host Resources: Point to Resources](#point-to-resources)):\n[https://cdn.jsdelivr.net/npm/dynamsoft-document-scanner@1.4.0/dist/document-scanner.ui.xml](https://cdn.jsdelivr.net/npm/dynamsoft-document-scanner@1.4.0/dist/document-scanner.ui.xml).\n\nThis file defines the UI for `DocumentScannerView`. Since files on the CDN **cannot be modified directly**, you must use a **local version** to customize the UI. `cameraEnhancerUIPath` specifies the file path to this local version of the UI.\n\n##### Steps to Customize the UI for `DocumentScannerView`\n\n1. Follow the instructions in [Build from Source](#build-from-source) to obtain the source files for **MDS**.\n\n2. Edit the existing `/src/dcv-config/document-scanner.ui.xml` to apply your customizations.\n\n3. Build the project to generate the updated file in `/dist/document-scanner.ui.xml`:\n\n   ```shell\n   npm run build\n   ```\n\n4. Update the configuration to use the local file instead of the CDN version:\n\n   ```javascript\n   const documentScanner = new Dynamsoft.DocumentScanner({\n     license: \"YOUR_LICENSE_KEY_HERE\", // Replace with your actual license key\n     scannerViewConfig: {\n       cameraEnhancerUIPath: \"../dist/document-scanner.ui.xml\", // Use the local file\n     },\n   });\n   ```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentScannerViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerviewconfig)\n\n##### Customizing the Scanning Region\n\nWe can customize the scanning region in the viewfinder with the `scanRegion` property in the configuration object. You may want to do this if you want to only scan your document in a specific sub-region in the viewfinder.\n\n```typescript\ninterface ScanRegion {\n  ratio: {\n    width: number;\n    height: number;\n  };\n  regionBottomMargin: number; // Bottom margin calculated in pixel\n  style: {\n    strokeWidth: number;\n    strokeColor: string;\n  };\n}\n```\n\nAPI Reference:\n\n[`ScanRegion`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#scanregion)\n\nHere is how `ScanRegion` applies its settings to the viewfinder:\n\n1. Use the `ratio` property to set the height-to-width of the rectangular scanning region, then scale the rectangle up to fit within the viewfinder.\n2. Translate the rectangular up by the number of pixels specified by `regionBottomMargin`.\n3. Create a visual border for the scanning region boundary on the viewfinder with a given stroke width in pixels, and a stroke color.\n\nFor example:\n\n```javascript\nscanRegion {\n  ratio: {\n    width: 2;\n    height: 3;\n  };\n  regionBottomMargin: 20;\n  style: {\n    strokeWidth: 3;\n    strokeColor: \"green\";\n  };\n}\n```\n\nThis creates a scan region with a height-to-width ratio of 3:2, translated upwards by 20 pixels, with a green, 3 pixel-wide border in the viewfinder.\n\n#### `DocumentCorrectionView` Configuration\n\nThe following configuration interface customizes the `DocumentCorrectionView`:\n\n```typescript\ninterface DocumentCorrectionViewConfig {\n  container?: HTMLElement;\n  toolbarButtonsConfig?: DocumentCorrectionViewToolbarButtonsConfig;\n  onFinish?: (result: DocumentScanResult) =\u003e void;\n}\n```\n\nThis section omits the `container` option, as we cover it in the [Workflow Customization](#workflow-customization) section. Below we discuss the other two properties.\n\n##### Styling `DocumentCorrectionView` Buttons\n\nThe `toolbarButtonsConfig` property (of type `DocumentCorrectionViewToolbarButtonsConfig`) customizes the **appearance and functionality** of the UI buttons. Here is its definition:\n\n```typescript\ntype ToolbarButtonConfig = Pick\u003cToolbarButton, \"icon\" | \"label\" | \"isHidden\"\u003e;\ninterface DocumentCorrectionViewToolbarButtonsConfig {\n  fullImage?: ToolbarButtonConfig;\n  detectBorders?: ToolbarButtonConfig;\n  apply?: ToolbarButtonConfig;\n}\n```\n\nWe can use it to **change the icon and label** of each of the three buttons individually or even **hide the buttons**. Below is an example that sets a custom label and image icon for the \"Detect Borders\" button and hides the \"Full Image\" button:\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  correctionViewConfig: {\n    toolbarButtonsConfig: {\n      fullImage: {\n        isHidden: true,\n      },\n      detectBorders: {\n        icon: \"path/to/new_icon.png\", // Change to the actual path of the new icon\n        label: \"Custom Label\",\n      },\n    },\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentCorrectionViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentcorrectionviewconfig)\n\n##### Customizing Apply Button Callback\n\nThe `onFinish` callback triggers upon having applied the user's corrections. For example, the code below displays the corrected image in a `resultContainer` after the user clicks \"Apply\":\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  correctionViewConfig: {\n    onFinish: (result) =\u003e {\n      const canvas = result.correctedImageResult.toCanvas();\n      resultContainer.appendChild(canvas);\n    },\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentCorrectionViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentcorrectionviewconfig)\n\n#### `DocumentResultView` Configuration\n\nConsider `toolbarButtonsConfig`, `onDone` and `onUpload` from the `DocumentResultViewConfig` configuration interface to customize the `DocumentResultView`:\n\n```typescript\ninterface DocumentResultViewConfig {\n  container?: HTMLElement;\n  toolbarButtonsConfig?: DocumentResultViewToolbarButtonsConfig;\n  onDone?: (result: DocumentResult) =\u003e Promise\u003cvoid\u003e;\n  onUpload?: (result: DocumentResult) =\u003e Promise\u003cvoid\u003e;\n}\n```\n\n##### Styling `DocumentResultView` Buttons\n\nThe `toolbarButtonsConfig` property, of type `DocumentResultViewToolbarButtonsConfig`, customizes the appearance and functionality of the UI buttons. Here is its definition:\n\n```typescript\ntype ToolbarButtonConfig = Pick\u003cToolbarButton, \"icon\" | \"label\" | \"isHidden\"\u003e;\ninterface DocumentResultViewToolbarButtonsConfig {\n  retake?: ToolbarButtonConfig;\n  correct?: ToolbarButtonConfig;\n  share?: ToolbarButtonConfig;\n  upload?: ToolbarButtonConfig;\n  done?: ToolbarButtonConfig;\n}\n```\n\nThis property can **change the icon and label** of each of the three buttons individually in the `DocumentResultView` or even **hide the buttons**. Below is an example that sets a custom label and image icon for the \"Retake\" button, and hides the \"Share\" button:\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  resultViewConfig: {\n    toolbarButtonsConfig: {\n      retake: {\n        icon: \"path/to/new_icon.png\", // Change to the actual path of the new icon\n        label: \"Custom Label\",\n      },\n      share: {\n        isHidden: true,\n      },\n    },\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentResultViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentresultviewconfig)\n\n##### Customizing the \"Done\" Button Callback\n\nThe `onDone` callback triggers upon pressing the \"Done\" button. For example, the code below displays the result image in a `resultContainer` after the user clicks \"Done\":\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  resultViewConfig: {\n    onDone: async (result) =\u003e {\n      const canvas = result.correctedImageResult.toCanvas();\n      resultContainer.appendChild(canvas);\n    },\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentResultViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentresultviewconfig)\n\n##### Customizing the \"Upload\" Button\n\nThe `onUpload` callback triggers upon pressing the \"Upload\" button. Note that the \"Upload\" button _only appears_ if a callback function is defined for `onUpload`; the button remains hidden otherwise.\n\nThe following example demonstrates how to upload the result image to a server:\n\n\u003e The following code applies if you follow the steps in [Build from Source](#build-from-source) and use the predefined express server setup. The scanned image uploads directly to the dev server as \"uploadedFile.png\". See the server configuration details in [`/dev-server/index.js`](https://github.com/Dynamsoft/document-scanner-javascript/blob/main/dev-server/index.js) for more details.\n\n```javascript\nconst documentScanner = new Dynamsoft.DocumentScanner({\n  license: \"YOUR_LICENSE_KEY_HERE\", // Replace this with your actual license key\n  resultViewConfig: {\n    onUpload: async (result) =\u003e {\n      const host = window.location.origin;\n      const blob = await result.correctedImageResult.toBlob();\n      // Create form data\n      const formData = new FormData();\n      formData.append(\"uploadFile\", blob, \"uploadedFile.png\");\n      // Upload file\n      const response = await fetch(\n        `${host}/upload`, // Change this to your actual upload URL\n        {\n          method: \"POST\",\n          body: formData,\n        }\n      );\n    },\n  },\n});\n```\n\nAPI Reference:\n\n- [`DocumentScanner()`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscanner)\n- [`DocumentScannerConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentscannerconfig)\n- [`DocumentResultViewConfig`](https://www.dynamsoft.com/mobile-document-scanner/docs/web/api/index.html#documentresultviewconfig)\n\n## Next Step\n\n**MDS** is a fully functional, ready-to-use scanning SDK with built-in UI layouts. For multi-page and **multi-document processing**, as well as advanced editing features, we developed **Mobile Web Capture (MWC)**. Read on to learn how to use this web-based wrapper SDK in the [**Mobile Web Capture User Guide**](https://www.dynamsoft.com/mobile-document-scanner/docs/web/code-gallery/mobile-web-capture/index.html).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynamsoft%2Fdocument-scanner-javascript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdynamsoft%2Fdocument-scanner-javascript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynamsoft%2Fdocument-scanner-javascript/lists"}