> For the complete documentation index, see [llms.txt](https://docs.accurascan.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.accurascan.com/language/web-plugin/id-plugin/svelte.md).

# Svelte

## Accura IDScan Plugin — Svelte Integration Guide

This guide walks you through integrating the **Accura IDScan Plugin** into a Svelte project built with Vite.

### Step 1: Initialize Project

If you do not have an existing Svelte project, scaffold one using Vite:

```bash
npm create vite@latest my-id-app -- --template svelte
cd my-id-app
npm install
```

***

### Step 2: Install Plugin

Install the Accura IDScan Plugin package from the npm registry:

```bash
npm install accuraidscanplugin
```

***

### Step 3: Implementation

Create a dedicated scanner component at `src/lib/IDScanner.svelte`. The following snippet shows only the **plugin import and initialization** logic:

```svelte
<script>
  import { onMount, onDestroy } from 'svelte';

  let plugin = null; // Holds the active plugin instance for lifecycle management

  onMount(async () => {
    // Dynamically import the plugin inside onMount to guarantee browser-only execution.
    // Svelte's onMount lifecycle hook runs exclusively on the client side,
    // making it safe to access browser APIs such as the camera.
    const { default: IDCardPlugin } = await import('accuraidscanplugin');

    // Instantiate the plugin with:
    //   1. The capture callback invoked when the scan session is complete
    //   2. A configuration object specifying the target card and UI appearance
    plugin = new IDCardPlugin(
      handleCapture,   // Fired automatically upon successful ID card scan
      {
        countryCode: "UGA",    // Country code of the ID Card
        cardCode: "UGNIDF",    // Card code of front ID Card
        topTextSize: "",       // Top overlay text size (default if empty)
        topTextColor: "",      // Top overlay text color (default if empty)
        topTextWeight: "",     // Top overlay font weight (default if empty)
        bottomTextSize: "",    // Bottom overlay text size (default if empty)
        bottomTextColor: "",   // Bottom overlay text color (default if empty)
        bottomTextWeight: "",  // Bottom overlay font weight (default if empty)
      }
    );

    // Activate the camera and begin the ID card detection session.
    await plugin.start();
  });

  // Release camera resources and destroy the plugin when the component is removed from the DOM.
  onDestroy(() => {
    if (plugin) {
      plugin.destroy();
    }
  });
</script>
```

***

### Step 4: Response Handling

When the plugin completes an ID card scan, it invokes the **`handleCapture`** callback with a payload object. This object may contain one or both of the following properties:

| Property | Type     | Description                                                     |
| -------- | -------- | --------------------------------------------------------------- |
| `front`  | `string` | Base64 Data URL of the front side of the ID card                |
| `back`   | `string` | Base64 Data URL of the back side of the ID card (if applicable) |

**What is Base64?** Base64 is a binary-to-text encoding scheme that converts raw binary image data into a sequence of printable ASCII characters. Each scanned card image is delivered as a Data URL string (e.g., `data:image/jpeg;base64,/9j/...`), combining a MIME type prefix with the encoded image payload. Before transmitting to a server, this string must be decoded back into binary form (a `Blob`) to construct a valid multipart HTTP request.

The following demonstrates the **base64-to-Blob conversion** and API submission:

```js
// Utility: converts a base64 Data URL string into a binary Blob.
// Multipart form uploads require raw binary data, not text-encoded Base64 strings.
const base64ToBlob = (base64DataURL) => {
    // Split at the comma: left side = MIME header, right side = encoded image data.
    const [meta, content] = base64DataURL.split(",");

    // Extract the MIME type (e.g., "image/jpeg") from the header segment.
    const mimeMatch = meta.match(/:(.*?);/);
    const mime = mimeMatch ? mimeMatch[1] : "image/jpeg";

    // Decode the base64-encoded payload back into raw binary characters using atob().
    const binary = atob(content);

    // Allocate a typed Uint8Array to hold the reconstructed binary bytes.
    const array = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i++) {
        array[i] = binary.charCodeAt(i); // Map each character to its corresponding byte value
    }

    // Wrap the reconstructed binary data in a Blob with the correct MIME type.
    return new Blob([array], { type: mime });
};

// Submits a card image Blob to the server-side verification endpoint.
const sendToAPI = async (blob, isface, card_code, filename) => {
    const formData = new FormData();
    formData.append("scan_image", blob, filename);  // Binary image file
    formData.append("isface", isface);              // "front" or "back"
    formData.append("country_code", "UGA");         // ISO country code
    formData.append("card_code", card_code);        // Card template identifier
    formData.append("passport", "false");           // "true" for passport documents
    formData.append("webcam", "false");             // "true" if captured via webcam

    try {
        const response = await fetch("http://ip:port/doc_liveness.php", {
            method: "POST",
            body: formData,
        });
        const data = await response.json();
        console.log(`API Response (${isface}):`, data);

        if (data && data.score !== undefined) {
            console.log(`Score (${isface}): ${data.score}`);
        }
    } catch (error) {
        console.error(`Error sending ${isface} to API:`, error);
    }
};

// Primary capture callback — invoked by the plugin when scanning is complete.
const handleCapture = async (base64) => {
    if (base64.front) {
        const frontBlob = base64ToBlob(base64.front);
        await sendToAPI(frontBlob, "front", "UGNIDF", "front.jpg");
    }
    if (base64.back) {
        const backBlob = base64ToBlob(base64.back);
        await sendToAPI(backBlob, "back", "UGNIDB", "back.jpg");
    }
};
```

***

### Step 5: Demo Implementation

The following is the **complete, production-ready component**. Copy and paste it directly into `src/lib/IDScanner.svelte`. The original logic is preserved exactly as-is.

```svelte
<script>
  import { onMount, onDestroy } from 'svelte';
  
  let isReady = false;
  let plugin = null;

  onMount(async () => {
    try {
      const { default: IDCardPlugin } = await import('accuraidscanplugin');

      const base64ToBlob = (base64DataURL) => {
        const [meta, content] = base64DataURL.split(",");
        const mimeMatch = meta.match(/:(.*?);/);
        const mime = mimeMatch ? mimeMatch[1] : "image/jpeg";
        const binary = atob(content);
        const array = new Uint8Array(binary.length);
        for (let i = 0; i < binary.length; i++) {
            array[i] = binary.charCodeAt(i);
        }
        return new Blob([array], { type: mime });
    };

    const sendToAPI = async (blob, isface, card_code, filename) => {
        const formData = new FormData();
        formData.append("scan_image", blob, filename);
        formData.append("isface", isface);
        formData.append("country_code", "UGA");
        formData.append("card_code", card_code);
        formData.append("passport", "false");
        formData.append("webcam", "false");

        try {
            console.log(`Sending ${isface} (${card_code}) to API...`);
            const response = await fetch("http://ip:port/doc_liveness.php", {
                method: "POST",
                body: formData,
            });

            const data = await response.json();
            console.log(`API Response (${isface}):`, data);

            if (data && data.score !== undefined) {
                console.log(`Score (${isface}): ${data.score}`);
            }
        } catch (error) {
            console.error(`Error sending ${isface} to API:`, error);
        }
    };


    const handleCapture = async (base64) => {
        console.log("Capture result received:", Object.keys(base64));

        if (base64.front) {
            console.log("Processing front side...");
            const frontBlob = base64ToBlob(base64.front);
            await sendToAPI(frontBlob, "front", "UGNIDF", "front.jpg");
        }
        if (base64.back) {
            console.log("Processing back side...");
            const backBlob = base64ToBlob(base64.back);
            await sendToAPI(backBlob, "back", "UGNIDB", "back.jpg");
        }
    };
      
      plugin = new IDCardPlugin(
        handleCapture,
        {
        countryCode: "UGA",
        cardCode: "UGNIDF",
        topTextSize: "",
        topTextColor: "",
        topTextWeight: "",
        bottomTextSize: "",
        bottomTextColor: "",
        bottomTextWeight: "",
      }
      );
      
      await plugin.start();
      isReady = true;
    } catch (e) {
      console.error("Svelte IDScan Error:", e);
    }
  });

  onDestroy(() => {
    if (plugin) {
      plugin.destroy();
    }
  });
</script>
```

***

### Step 6: Usage

Import and render the component in `App.svelte`:

```svelte
<script>
  import IDScanner from './lib/IDScanner.svelte';
</script>

<IDScanner />
```

***

### Step 7: Running the Project

```bash
npm run dev
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.accurascan.com/language/web-plugin/id-plugin/svelte.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
