> 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/face-plugin/react.md).

# React

## Accura Face Plugin — React Integration Guide

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

***

### Prerequisites

Before proceeding, ensure the following requirement is met:

* **`accura.xml`** — Place your `accura.xml` file in the **`public/`** folder of your project as `public/accura.xml`. This file is required by the plugin to initialize the face detection engine. You can download it from here.

{% file src="/files/UYRDaSONHcarfdtCAsOg" %}

> The `public/` directory is served as static assets in Vite-based projects, making the file accessible at runtime via the path `/accura.xml`.

***

### Step 1: Initialize Project

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

```bash
npm create vite@latest my-face-app -- --template react
cd my-face-app
npm install
```

***

### Step 2: Install Plugin

Install the Accura Face Plugin package from the npm registry:

```bash
npm install accurafaceplugin
```

***

### Step 3: TypeScript Support *(Recommended)*

If your project uses TypeScript, create a type declaration file at `src/types.d.ts` to suppress module resolution warnings and enable IDE intellisense:

```typescript
declare module 'accurafaceplugin' {
  export default class FacePlugin {
    constructor(
      xmlPath: string,
      callback: (data: { base64: string }) => void,
      config: Record<string, string | number>
    );
    start(): Promise<void>;
    destroy(): void;
  }
}
```

Ensure this file is included in your `tsconfig.app.json`'s `include` array:

```json
"include": ["src"]
```

***

### Step 4: Implementation

Create a dedicated component file at `src/FaceScanner.jsx` (or `.tsx` for TypeScript). The following snippet shows only the **plugin import and initialization** logic:

```jsx
import { useEffect, useRef } from 'react';

const FaceScanner = () => {
    const pluginRef = useRef(null);    // Holds the active plugin instance across renders
    const initialized = useRef(false); // Guards against double-initialization in Strict Mode

    useEffect(() => {
        // Prevent re-initialization caused by React Strict Mode's double-invocation behavior
        if (initialized.current) return;
        initialized.current = true;

        const initPlugin = async () => {
            // Dynamically import the plugin to ensure it runs only in the browser context.
            // This prevents errors in SSR environments and improves initial bundle performance.
            const { default: FacePlugin } = await import('accurafaceplugin');

            // Instantiate FacePlugin with the license path, capture callback, and config options.
            pluginRef.current = new FacePlugin(
                "/accura.xml",   // Publicly accessible path to the license file (from public/)
                base64Handler,   // Callback function invoked on successful face capture
                {
                    threshold: 3,       // Detection threshold (1–100; higher = stricter)
                    textSize: "",       // Instruction overlay text size (default if empty)
                    textColor: "",      // Instruction overlay text color (default if empty)
                    textWeight: "",     // Instruction overlay font weight (default if empty)
                    textBgColor: "",    // Instruction overlay background color (default if empty)
                    BodyBgColor: "",    // Camera viewport background color (default if empty)
                }
            );

            // Initialize the camera and begin the face detection lifecycle.
            await pluginRef.current.start();
        };

        initPlugin().catch(console.error);

        // Cleanup: destroy the plugin instance when the component unmounts
        // to release camera resources and prevent memory leaks.
        return () => {
            if (pluginRef.current) {
                pluginRef.current.destroy();
            }
        };
    }, []);

    return <></>;
};
```

***

### Step 5: Response Handling

When the plugin successfully detects and captures a face, it fires the **`base64Handler`** callback. This callback receives a single argument — an object containing a `base64` property. The value is a Data URL string encoding the captured face image in Base64 format (e.g., `data:image/jpeg;base64,/9j/...`).

**What is Base64?** Base64 is a binary-to-text encoding mechanism that expresses raw binary image data as a printable ASCII string. The prefix (e.g., `data:image/jpeg;base64,`) identifies the MIME type of the image. The remainder is the encoded pixel data, which can be directly transmitted over HTTP without binary transfer protocols.

The following handler demonstrates extracting the value and forwarding it to a remote verification endpoint:

```jsx
// Called automatically by the plugin upon successful face capture.
// Receives: { base64 } — a complete Data URL string of the captured face image.
const base64Handler = async ({ base64 }) => {
    console.log("Base64 received:", base64);

    try {
        // Build a multipart form payload for HTTP transmission.
        const formData = new FormData();

        // Attach the base64-encoded image string under the key your backend expects.
        formData.append("imagebase64", base64);

        // Submit the payload to your server-side verification endpoint via POST.
        // Replace the URL with your actual backend address.
        const response = await fetch("https://ip:port/upload.php", {
            method: "POST",
            body: formData,
        });

        // Deserialize the JSON response from the verification server.
        const data = await response.json();
        console.log("API Response:", data);

        // Read the liveness/match confidence score from the response.
        if (data && data.score !== undefined) {
            console.log(`Score: ${data.score}`);
        }
    } catch (error) {
        console.error("Error sending to API:", error);
    }
};
```

***

### Step 6: Demo Implementation

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

```jsx
import React, { useEffect, useRef, useState } from 'react';
import type FacePlugin from "accurafaceplugin";

const FaceScanner = () => {
    const [isReady, setIsReady] = useState(false);
    const pluginRef = useRef<FacePlugin | null>(null);

    useEffect(() => {
        const initPlugin = async () => {
            try {
                // Load plugin dynamically for SSR safety and clean bundling
                const { default: FacePlugin } = await import('accurafaceplugin');

                const base64Handler = async ({ base64 }: { base64: string }) => {
                    console.log("Base64 received:", base64);

                    try {
                        const formData = new FormData();
                        formData.append("imagebase64", base64);
                        // formData.append("image2base64", base64);

                        const response = await fetch(
                            "https://ip:port/upload.php",
                            {
                                method: "POST",
                                body: formData,
                            },
                        );

                        const data = await response.json();
                        console.log("API Response:", data);

                        // Display the score on UI
                        if (data && data.score !== undefined) {
                            console.log(`Score: ${data.score}`);
                        }
                    } catch (error) {
                        console.error("Error sending to API:", error);
                    }
                };

                pluginRef.current = new FacePlugin(
                    "/accura.xml", // Path to license in public folder
                    base64Handler,
                    {
                        threshold: 3,
                        textSize: "",
                        textColor: "",
                        textWeight: "",
                        textBgColor: "",
                        BodyBgColor: "",
                    }
                );

                await pluginRef.current.start();
                setIsReady(true);
            } catch (error) {
                console.error("Plugin initialization failed:", error);
            }
        };

        initPlugin();

        // Cleanup on unmount
        return () => {
            if (pluginRef.current) {
                pluginRef.current.destroy();
            }
        };
    }, []);

    return (
        <></>
    );
};

export default FaceScanner;
```

***

### Step 7: Usage

Import and render the `FaceScanner` component in your `App.jsx`:

```jsx
import FaceScanner from './FaceScanner';

export default function App() {
  return (
    <div className="App">
      <FaceScanner />
    </div>
  );
}
```

> **Note:** Remove the `<StrictMode>` wrapper from `main.jsx` or `main.tsx` if present, as React Strict Mode invokes lifecycle hooks twice in development, which can cause duplicate plugin initialization.

***

### Step 8: 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/face-plugin/react.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.
