# Genius Scan SDK for the Web

## Description

The Genius Scan SDK for the Web enables you to integrate the document scanning experience that powers the [Genius Scan app](tglapp.com/scan) in your web app.

It offers a component enabling you to implement the [Genius Scan SDK](https://geniusscansdk.com) Scan Flow, an all-in-one configurable scanner module with the following key features:

- Automatic document detection
- Document perspective correction
- Image enhancement filters with 4 different modes (Black & white, Monochrome, Color, Photo)
- Batch scanning of several pages in row

Some of the features of the native SDK, such as OCR and PDF generation, are not available currently in the Web SDK.

## License

You can try the "demo" version for free without a license key, the only limitation being that the app will need reloading after 60 seconds.

You need to [set a license key](#set-the-license-key) for unlimited demo time, or for production.

To buy a license:

1. [Sign up](https://portal.geniusscansdk.com/apps) to our developer console
2. Submit a quote request for each application, using your application hostname as an App ID. For example, if you are hosting your application on "https://app.mydomain.com", you will need to register a license for `app.mydomain.com`

You can learn more about [licensing](https://geniusscansdk.com/license/licensing) in our website and contact us at sales@geniusscansdk.com for further questions.

## Demo application

As an example, you can check the [demo web application](https://demo.geniusscansdk.com)

The demo's source code is available at https://github.com/thegrizzlylabs/geniusscan-sdk-demo/tree/master/web.

## Usage

### Prerequisite: Content Security Policy

If your page uses Content Security Policy (CSP), you will need the following exceptions so that the Genius Scan SDK can install itself on the page:

- `connect-src 'self' data:;`
- `worker-src 'self' blob:;`
- `script-src 'self' 'unsafe-eval';`
- `style-src 'self' 'unsafe-inline';`

**Note:** If you're using the script tag approach with a CDN, make sure to include the appropriate CDN domain in your `script-src` directive (e.g., `https://cdn.jsdelivr.net`).

### Set the license key

Initialize the SDK with a valid license key:

```javascript
// index.js
import { setLicenseKey, scanWithConfiguration } from "@thegrizzlylabs/web-geniusscan-sdk";
const LICENSE_KEY_FOR_YOUR_DOMAIN = "xxxxxx";

setLicenseKey(LICENSE_KEY_FOR_YOUR_DOMAIN).catch((e) => {
  console.error(`Error setting Genius Scan SDK license key`, e);
});
```

Note that, for testing purpose, you can also use the plugin without setting a license key, but it will only work for 60 seconds.

### Start the scanner module

This short guide will walk you through the steps to add a scan workflow to your existing web application.

1. Add `@thegrizzlylabs/web-geniusscan-sdk` to your project:

```sh
npm install --save @thegrizzlylabs/web-geniusscan-sdk
```

2. Import the library, set the license key and run the scan workflow. This is a simple vanilla JS example:

```html
<!-- index.html -->

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Genius Scan - Simple demo</title>
    <script src="index.js" type="module"></script>
  </head>
  <body>
    <main>
      <h1>Genius Scan Web SDK demo</h1>
      <div id="container">
        <button id="scan">
          <span class="button-text">Scan document</span>
        </button>
        <div class="scanned-images"></div>
        <div class="pdf-download"></div>
      </div>
    </main>
  </body>
</html>
```

```javascript
// index.js

import { scanWithConfiguration } from "@thegrizzlylabs/web-geniusscan-sdk";

// This code shows how to initialize the SDK with a license key.
//
//
// import { setLicenseKey } from "@thegrizzlylabs/web-geniusscan-sdk";
//
// setLicenseKey(<Your license key>).catch((e) => {
//   console.error(`Error setting Genius Scan SDK license key`, e);
// });

const scanButton = document.getElementById("scan");
const scannedImages = document.querySelector(".scanned-images");
const pdfDownload = document.querySelector(".pdf-download");

scanButton.addEventListener("click", async () => {
  try {
    const { scans, multiPageDocument } = await scanWithConfiguration({
      highlightColor: "#ffa500",
      multiPageFormat: "pdf",
      multiPage: true,
    });

    scannedImages.innerHTML = "";
    pdfDownload.innerHTML = "";

    let imageIndex = 1;
    for (const scan of scans) {
      const url = URL.createObjectURL(scan.enhancedImage.data);
      const a = document.createElement("a");
      a.href = url;
      a.download = `scanned-document-${imageIndex}.jpg`;
      a.title = "Click to download";
      const img = document.createElement("img");
      img.src = url;
      img.alt = "Scanned document";
      img.unload = () => {
        URL.revokeObjectURL(url);
      };
      a.appendChild(img);
      scannedImages.appendChild(a);
      imageIndex++;
    }

    if (multiPageDocument) {
      const blob = new Blob([multiPageDocument.data], { type: multiPageDocument.type });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.textContent = "Download PDF";
      a.download = `${Date.now()}-scanned-documents`;
      pdfDownload.appendChild(a);
    }
  } catch (error) {
    console.error(error);
    alert(`Error scanning document: ${error.message}`);
  }
});
```

### Alternative: loading the library as a script tag

You can also use the Genius Scan SDK directly in the browser without a build step by including it as a script tag:

```html
<script src="https://cdn.jsdelivr.net/npm/@thegrizzlylabs/web-geniusscan-sdk@latest/dist/geniusscan-sdk.iife.js"></script>
```

**Note:** For production use, we recommend using a fixed version number instead of `@latest` to ensure consistent behavior and avoid unexpected breaking changes. For example: `@thegrizzlylabs/web-geniusscan-sdk@5.12.0`.

When using the script tag, the SDK is available globally as `GSSDK` and provides the same API as the module version.

## Scan Configuration

The method `scanWithConfiguration()` accepts an optional `configuration` object as parameter which can take the following attributes:

### Scanning options

- `source`: string (defaults to `"camera"`). Where the input image comes from. Possible values are `"camera"` (live camera), `"gallery"` (system file picker), and `"image"` (a pre-provided image). Multi-page scanning is only available when `source` is `"camera"`.
- `sourceImage`: a `Blob` or `File`. Required when `source` is `"image"`. The SDK processes this image and opens the enhance step directly, without showing the camera or a file picker.
- `multiPage`: boolean (defaults to true). If true, after a page is scanned, a prompt to scan another page will be displayed. If false, a single page will be scanned. Only applies when `source` is `"camera"`.
- `multiPageFormat`: string (defaults to "pdf"). The format of the multi-page document that will be generated. Possible values are `"none"` (no document generation) or `"pdf"` (PDF document).
- `defaultFilter`: the filter that will be applied by default to enhance scans, or `"none"` if no enhancement should be performed by default. Possible values are listed in `availableFilters`. Default value is `"automatic"`.
- `availableFilters`: an array of filters that the user can select when they tap on the edit filter button. Defaults to `["automatic", "strong_monochrome", "soft_grayscale", "soft_color", "strong_grayscale", "strong_color", "photo", "dark_background", "none"]`.
- `jpegQuality`: JPEG quality used to compress captured images. Between 0 and 100, 100 being the best quality. Default is 60.
- `postProcessingActions`: an array with the desired actions to display during the post-processing screen (defaults to all actions). Possible actions are `rotate`, `editFilter`, and `correctDistortion`.
- `outputOriginalImage`: boolean (default to false). If true, the result `scans` will also include `originalImage` data. This will lead to higher memory consumption on the web page.

### PDF options

- `pdfPageSize`: the page size for PDF generation when `multiPageFormat` is set to `"pdf"`. Possible values are `"fit"` (fits the page to the content, default), `"a4"` (A4 format: 8.27" × 11.69"), or `"letter"` (US Letter format: 8.5" × 11.0"`)
- `pdfTitle`: PDF file title attribute. Default to: `"Scanned Documents".

### Look and feel options

- `foregroundColor`: string representing a color, must start with a `#`. The color of the icons and text (defaults to '#ffffff').
- `backgroundColor`: string representing a color, must start with a `#`. The color of the toolbar and screen background (defaults to black).
- `highlightColor`: string representing a color, must start with a `#`. The color of the image overlays (defaults to blue).
- `language`: change the scan flow localization. Possible values are `"en", "ar", "da", "de", "es", "fr", "hu", "in", "it", "iw", "ja", "ko", "nl", "pl", "pt", "ru", "sv", "tr", "vi", "zh-CN", "zh-TW"`. Default value is `"en"`

_Note: For the Web SDK, you may use either hex color values (e.g., `#ffffff`) or [standard CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#color_keywords) (e.g., `"orange"`, `"cornflowerblue"`) for color-related options. Both formats are supported. _

## Return Values

The `scanWithConfiguration()` function returns a Promise that resolves to an object with the following properties:

- `scans`: an array of scanned page objects. Each scan object contains:
  - an `enhancedImage` attribute that contains:
    - a `data` attribute: a Blob containing the image data
    - a `type` attribute: the MIME type of the image (e.g., `"image/jpeg"`)
  - if `outputOriginalImage` parameter is `true`, an `originalImage` object which also contain `data` and `type` attributes
- `multiPageDocument`: a multi-page document object (only present if `multiPageFormat` is not `"none"`). The object contains:
  - `data`: a Blob containing the document data
  - `type`: the MIME type of the document (e.g., `"application/pdf"`)
