npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jaak.ai/stamps

v2.3.0

Published

Jaak Document Identifier

Readme

Jaak Stamps Web Component

npm version License: MIT

📖 Versión en Español

Description

Jaak Stamps is a powerful web component for document scanning and capture using camera input with AI-powered document detection. The component provides a complete solution for capturing high-quality document images with real-time detection feedback and automated cropping capabilities.

Key Features

  • AI-Powered Document Detection: Automatically detects and frames documents in the camera view
  • Dual-Side Capture: Supports both front and back document capture workflow
  • Real-time Preview: Live camera feed with detection overlays and guidance
  • Multi-Camera Support: Automatic camera selection with manual override options
  • Smart Cropping: Automatic document boundary detection and cropping
  • Mobile Optimized: Responsive design that works across all device sizes
  • Web Standards Compliant: Built as a standard Web Component for maximum compatibility

Typical Use Cases

  • Identity Verification: Capture ID cards, passports, and driver's licenses
  • Document Digitization: Scan contracts, certificates, and legal documents
  • KYC/AML Processes: Streamlined identity document capture for compliance
  • Form Processing: Digitize paper forms and applications
  • Insurance Claims: Capture damage reports and supporting documentation

Installation

NPM/Yarn

# Using npm
npm install @jaak.ai/stamps

# Using yarn
yarn add @jaak.ai/stamps

CDN

<!-- ES Module -->
<script type="module" src="https://unpkg.com/@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js"></script>

<!-- With Loader -->
<script type="module">
  import { defineCustomElements } from 'https://unpkg.com/@jaak.ai/stamps/loader/index.js';
  defineCustomElements();
</script>

API Reference

Properties/Attributes

License Properties (Required)

| Property | Type | Default | Description | |----------|------|---------|-------------| | license | string | undefined | [REQUIRED] License key for component authentication | | license-environment | 'dev' \| 'qa' \| 'sandbox' \| 'prod' | 'prod' | API environment for license validation | | app-id | string | 'jaak-stamps-web' | Application identifier for analytics and tracking | | trace-id | string | undefined | Optional trace ID for distributed tracing (auto-generated if not provided) |

Base Configuration Properties

| Property | Type | Default | Description | |----------|------|---------|-------------| | debug | boolean | false | Enable debug mode with additional logging and overlays | | mask-size | number | 90 | Size percentage of the document detection mask (50-100) | | alignment-tolerance | number | 15 | Tolerance level in pixels for document alignment detection | | capture-delay | number | 1500 | Delay in milliseconds before automatic capture (0-10000) | | crop-margin | number | 20 | Margin in pixels around detected document for cropping (0-100) | | preferred-camera | 'auto' \| 'front' \| 'back' | 'auto' | Preferred camera selection | | use-document-classification | boolean | false | Enable AI document type classification | | use-document-detector | boolean | true | Enable/disable AI document detection model | | enable-back-document-timer | boolean | false | Enable timer for back document capture | | back-document-timer-duration | number | 20 | Duration in seconds for back document capture timer |

Telemetry and OpenTelemetry Properties

| Property | Type | Default | Description | |----------|------|---------|-------------| | telemetry-collector-url | string | 'https://collector.jaak.ai/v1/traces' | OTLP collector URL for distributed traces | | metrics-collector-url | string | 'https://collector.jaak.ai/v1/metrics' | OTLP collector URL for metrics | | enable-telemetry | boolean | true | Enable distributed tracing with OpenTelemetry | | enable-metrics | boolean | true | Enable metrics export to OpenTelemetry | | metrics-export-interval-millis | number | 60000 | Metrics export interval in milliseconds | | propagate-trace-header-cors-urls | string | undefined | Comma-separated URLs for W3C Trace Context header propagation |

Context Properties

| Property | Type | Default | Description | |----------|------|---------|-------------| | customer-id | string | undefined | Customer ID for telemetry and analytics | | tenant-id | string | undefined | Tenant ID for multi-tenancy support | | environment | string | 'production' | Execution environment (development/staging/production) |

Methods

Camera Control

// Get information about available cameras
getCameraInfo(): Promise<CameraInfoResponse>

// Set preferred camera
setPreferredCamera(camera: "auto" | "front" | "back"): Promise<{
  success: boolean;
  selectedCamera: string;
  availableCameras: number;
}>

// Control device torch/flashlight
setTorchEnabled(enabled: boolean): Promise<{
  success: boolean;
  enabled: boolean;
}>

// Focus camera at specific point
focusAtPoint(x: number, y: number): Promise<{
  success: boolean;
  coordinates: { x: number; y: number };
}>

Capture Control

// Start the capture process
startCapture(): Promise<void>

// Stop the capture process
stopCapture(): Promise<void>

// Reset capture state
resetCapture(): Promise<void>

// Skip back document capture
skipBackCapture(): Promise<void>

Configuration

// Set capture delay
setCaptureDelay(delay: number): Promise<{
  success: boolean;
  captureDelay: number;
}>

// Get current capture delay
getCaptureDelay(): Promise<number>

Status & Data

// Get current component status
getStatus(): Promise<StatusResponse>

// Get captured images
getCapturedImages(): Promise<CapturedImagesResponse>

// Check if process is completed
isProcessCompleted(): Promise<boolean>

// Preload AI model
preloadModel(): Promise<{
  success: boolean;
  message?: string;
  error?: any;
}>

Events

| Event | Detail Type | Description | |-------|-------------|-------------| | isReady | boolean | Fired when component is fully initialized and ready | | captureCompleted | object | Fired when document capture process is completed | | traceIdGenerated | { traceId: string } | Fired after license validation with the generated or provided trace ID for request tracing |

Type Definitions

interface CameraInfoResponse {
  availableCameras: Array<{
    id: string;
    label: string;
    selected: boolean;
  }>;
  selectedCameraId: string | null;
  deviceType: string;
  isMultipleCamerasAvailable: boolean;
  preferredFacing: 'environment' | 'user' | null;
}

interface CapturedImagesResponse {
  front: {
    fullFrame: string | null;
    cropped: string | null;
  };
  back: {
    fullFrame: string | null;
    cropped: string | null;
  };
  metadata: {
    totalImages: number;
    processCompleted: boolean;
    backCaptureSkipped: boolean;
  };
}

interface StatusResponse {
  isVideoActive: boolean;
  captureStep: 'front' | 'back' | 'completed';
  hasImages: boolean;
  isProcessCompleted: boolean;
  isModelPreloaded: boolean;
}

Implementation Examples

Vanilla JavaScript

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="https://unpkg.com/@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js"></script>
</head>
<body>
  <jaak-stamps
    id="documentScanner"
    license="your-license-key-here"
    environment="prod"
    app-id="my-custom-app"
    preferred-camera="auto"
    capture-delay="1500"
    use-document-detector="true"
    debug="false">
  </jaak-stamps>

  <script>
    const scanner = document.getElementById('documentScanner');

    // Handle trace ID generation
    scanner.addEventListener('traceIdGenerated', (event) => {
      console.log('Trace ID for this session:', event.detail.traceId);
      // Use this trace ID for correlating requests across your system
    });

    // Wait for component to be ready
    scanner.addEventListener('isReady', () => {
      console.log('Document scanner is ready');

      // Start the capture process
      scanner.startCapture();
    });

    // Handle capture completion
    scanner.addEventListener('captureCompleted', async (event) => {
      console.log('Capture completed:', event.detail);

      // Get captured images
      const images = await scanner.getCapturedImages();
      console.log('Captured images:', images);

      // Process the images as needed
      if (images.front.cropped) {
        // Display or upload the cropped front image
        displayImage(images.front.cropped);
      }
    });
    
    function displayImage(base64Image) {
      const img = document.createElement('img');
      img.src = `data:image/jpeg;base64,${base64Image}`;
      document.body.appendChild(img);
    }
  </script>
</body>
</html>

React

import React, { useEffect, useRef, useState } from 'react';
import { defineCustomElements } from '@jaak.ai/stamps/loader';

// Define custom elements
defineCustomElements();

// Extend HTMLElement for TypeScript
declare global {
  namespace JSX {
    interface IntrinsicElements {
      'jaak-stamps': any;
    }
  }
}

interface CapturedImages {
  front: { fullFrame: string | null; cropped: string | null };
  back: { fullFrame: string | null; cropped: string | null };
  metadata: {
    totalImages: number;
    processCompleted: boolean;
    backCaptureSkipped: boolean;
  };
}

const DocumentScanner: React.FC = () => {
  const scannerRef = useRef<HTMLElement>(null);
  const [isReady, setIsReady] = useState(false);
  const [capturedImages, setCapturedImages] = useState<CapturedImages | null>(null);
  
  useEffect(() => {
    const scanner = scannerRef.current;
    if (!scanner) return;
    
    // Trace ID generation handler
    const handleTraceIdGenerated = (event: CustomEvent) => {
      console.log('Trace ID:', event.detail.traceId);
    };

    // Component ready handler
    const handleReady = () => {
      setIsReady(true);
    };

    // Capture completion handler
    const handleCaptureCompleted = async () => {
      const images = await (scanner as any).getCapturedImages();
      setCapturedImages(images);
    };

    // Add event listeners
    scanner.addEventListener('traceIdGenerated', handleTraceIdGenerated);
    scanner.addEventListener('isReady', handleReady);
    scanner.addEventListener('captureCompleted', handleCaptureCompleted);
    
    return () => {
      scanner.removeEventListener('traceIdGenerated', handleTraceIdGenerated);
      scanner.removeEventListener('isReady', handleReady);
      scanner.removeEventListener('captureCompleted', handleCaptureCompleted);
    };
  }, []);
  
  const startScan = async () => {
    if (scannerRef.current) {
      await (scannerRef.current as any).startCapture();
    }
  };
  
  return (
    <div>
      <h2>Document Scanner</h2>
      
      <jaak-stamps
        ref={scannerRef}
        license="your-license-key-here"
        environment="prod"
        app-id="my-react-app"
        trace-id=""  // Leave empty to auto-generate
        preferred-camera="auto"
        capture-delay={1500}
        use-document-classification={true}
        use-document-detector={true}
      />
      
      <div style={{ marginTop: '20px' }}>
        <button onClick={startScan} disabled={!isReady}>
          {isReady ? 'Start Scanning' : 'Loading...'}
        </button>
      </div>
      
      {capturedImages && (
        <div style={{ marginTop: '20px' }}>
          <h3>Captured Images</h3>
          {capturedImages.front.cropped && (
            <div>
              <h4>Front Document</h4>
              <img 
                src={`data:image/jpeg;base64,${capturedImages.front.cropped}`}
                alt="Front document"
                style={{ maxWidth: '300px' }}
              />
            </div>
          )}
          {capturedImages.back.cropped && (
            <div>
              <h4>Back Document</h4>
              <img 
                src={`data:image/jpeg;base64,${capturedImages.back.cropped}`}
                alt="Back document"
                style={{ maxWidth: '300px' }}
              />
            </div>
          )}
        </div>
      )}
    </div>
  );
};

export default DocumentScanner;

Angular

// document-scanner.component.ts
import { Component, ElementRef, ViewChild, AfterViewInit, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { defineCustomElements } from '@jaak.ai/stamps/loader';

// Define custom elements
defineCustomElements();

interface CapturedImages {
  front: { fullFrame: string | null; cropped: string | null };
  back: { fullFrame: string | null; cropped: string | null };
  metadata: {
    totalImages: number;
    processCompleted: boolean;
    backCaptureSkipped: boolean;
  };
}

@Component({
  selector: 'app-document-scanner',
  template: `
    <div class="scanner-container">
      <h2>Document Scanner</h2>
      
      <jaak-stamps
        #scanner
        license="your-license-key-here"
        environment="prod"
        app-id="my-angular-app"
        preferred-camera="auto"
        [capture-delay]="1500"
        [use-document-classification]="true"
        [use-document-detector]="true">
      </jaak-stamps>
      
      <div class="controls">
        <button 
          (click)="startScan()" 
          [disabled]="!isReady"
          class="scan-button">
          {{ isReady ? 'Start Scanning' : 'Loading...' }}
        </button>
        
        <button 
          (click)="resetScan()" 
          [disabled]="!isReady"
          class="reset-button">
          Reset
        </button>
      </div>
      
      <div *ngIf="capturedImages" class="results">
        <h3>Captured Images</h3>
        
        <div *ngIf="capturedImages.front.cropped" class="image-result">
          <h4>Front Document</h4>
          <img 
            [src]="'data:image/jpeg;base64,' + capturedImages.front.cropped"
            alt="Front document"
            class="captured-image">
        </div>
        
        <div *ngIf="capturedImages.back.cropped" class="image-result">
          <h4>Back Document</h4>
          <img 
            [src]="'data:image/jpeg;base64,' + capturedImages.back.cropped"
            alt="Back document"
            class="captured-image">
        </div>
        
        <div class="metadata">
          <p>Total Images: {{ capturedImages.metadata.totalImages }}</p>
          <p>Process Completed: {{ capturedImages.metadata.processCompleted }}</p>
        </div>
      </div>
    </div>
  `,
  styles: [`
    .scanner-container {
      max-width: 600px;
      margin: 0 auto;
      padding: 20px;
    }
    
    .controls {
      margin: 20px 0;
      display: flex;
      gap: 10px;
    }
    
    .scan-button, .reset-button {
      padding: 10px 20px;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
    
    .scan-button {
      background-color: #007bff;
      color: white;
    }
    
    .reset-button {
      background-color: #6c757d;
      color: white;
    }
    
    .scan-button:disabled, .reset-button:disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }
    
    .results {
      margin-top: 20px;
    }
    
    .image-result {
      margin: 20px 0;
    }
    
    .captured-image {
      max-width: 100%;
      height: auto;
      border: 1px solid #ddd;
      border-radius: 4px;
    }
    
    .metadata {
      background-color: #f8f9fa;
      padding: 10px;
      border-radius: 4px;
      margin-top: 20px;
    }
  `],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class DocumentScannerComponent implements AfterViewInit {
  @ViewChild('scanner', { static: false }) scannerRef!: ElementRef;
  
  isReady = false;
  capturedImages: CapturedImages | null = null;
  
  ngAfterViewInit() {
    const scanner = this.scannerRef.nativeElement;

    // Trace ID generation handler
    scanner.addEventListener('traceIdGenerated', (event: CustomEvent) => {
      console.log('Trace ID:', event.detail.traceId);
    });

    // Component ready handler
    scanner.addEventListener('isReady', () => {
      this.isReady = true;
    });

    // Capture completion handler
    scanner.addEventListener('captureCompleted', async () => {
      this.capturedImages = await scanner.getCapturedImages();
    });
  }
  
  async startScan() {
    if (this.scannerRef?.nativeElement) {
      await this.scannerRef.nativeElement.startCapture();
    }
  }
  
  async resetScan() {
    if (this.scannerRef?.nativeElement) {
      await this.scannerRef.nativeElement.resetCapture();
      this.capturedImages = null;
    }
  }
}
// app.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DocumentScannerComponent } from './document-scanner.component';

@NgModule({
  declarations: [DocumentScannerComponent],
  imports: [BrowserModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA], // Required for custom elements
  exports: [DocumentScannerComponent]
})
export class DocumentScannerModule { }

Telemetry and Observability (OpenTelemetry)

Jaak Stamps includes full OpenTelemetry integration for distributed tracing, metrics, and performance monitoring in production environments.

Distributed Tracing

The component implements distributed tracing following the W3C Trace Context standard, providing:

  • Complete flow tracking of document capture processes
  • Request correlation between frontend and backend
  • Performance bottleneck identification
  • Context propagation via traceparent headers

Automatically Recorded Spans:

  • component.initialize - Component initialization
  • capture.start - Capture process start
  • model.preload - AI model preloading
  • model.detection.load - Detection model loading
  • model.classification.load - Classification model loading

Performance Metrics

The component exports detailed metrics to OpenTelemetry:

Counters:

  • capture.counter - Number of completed captures
  • error.counter - Error count by type
  • model.load.counter - Model load count
  • user.interaction.counter - User interactions

Histograms (Latencies):

  • capture.latency - Total capture time
  • model.load.latency - Model loading time
  • detection.latency - Per-frame detection time
  • image.size - Captured image sizes

Gauges (Current State):

  • active.sessions - Active sessions
  • memory.usage - Memory usage

Telemetry Configuration

<jaak-stamps
  license="your-license-key"
  enable-telemetry="true"
  enable-metrics="true"
  telemetry-collector-url="https://collector.jaak.ai/v1/traces"
  metrics-collector-url="https://collector.jaak.ai/v1/metrics"
  metrics-export-interval-millis="60000"
  propagate-trace-header-cors-urls="https://api.example.com,https://backend.example.com"
  customer-id="customer123"
  tenant-id="tenant456"
  environment="production"
  trace-id="optional-custom-trace-id">
</jaak-stamps>

Using Trace ID

The component automatically generates a unique trace ID for each session, or accepts a custom one:

const scanner = document.getElementById('documentScanner');

// Listen for trace ID generation
scanner.addEventListener('traceIdGenerated', (event) => {
  const traceId = event.detail.traceId;
  console.log('Trace ID for this session:', traceId);

  // Use this traceId to correlate requests in your backend
  fetch('/api/process-document', {
    method: 'POST',
    headers: {
      'X-Trace-Id': traceId,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ /* data */ })
  });
});

Enriched Attributes

Traces and metrics automatically include:

  • User Agent: Browser, version, operating system
  • Geolocation: Country, region, city (when available)
  • Device Memory: Device memory capacity
  • Customer Context: customerId, tenantId, environment
  • Service Info: Service name, component version

Context Propagation (CORS)

To propagate traces to your backend services:

<jaak-stamps
  propagate-trace-header-cors-urls="https://api.example.com,https://services.example.com">
</jaak-stamps>

This automatically configures fetch and XMLHttpRequest interceptors to include the traceparent header in requests to those URLs.

Visualization with Jaeger/Zipkin

Exported traces are compatible with:

  • Jaeger - Distributed tracing system
  • Zipkin - Alternative tracing system
  • Grafana Tempo - Grafana trace backend
  • Any OTLP-compatible backend (OpenTelemetry Protocol)

License Validation

The component requires a valid license to function. Validation occurs automatically when the component loads.

License Configuration

<jaak-stamps
  license="your-license-key-here"
  license-environment="prod"
  app-id="my-application">
</jaak-stamps>

Available Environments

| Environment | Validation URL | Use Case | |-------------|---------------|----------| | dev | https://api.dev.jaak.ai | Local development | | qa | https://api.qa.jaak.ai | Quality assurance testing | | sandbox | https://api.sandbox.jaak.ai | Integration testing | | prod | https://services.api.jaak.ai | Production |

License Error Handling

If the license is invalid, the component will display an error and not function:

const scanner = document.getElementById('documentScanner');

scanner.addEventListener('isReady', (event) => {
  if (!event.detail) {
    console.error('Error: Invalid license or component not initialized');
  }
});

Common error messages:

  • "License key is required" - No license provided
  • "Invalid license key" - Invalid or expired license
  • "License validation failed" - Validation error

Style Guide

CSS Custom Properties

The component supports customization through CSS custom properties:

jaak-stamps {
  /* Camera view dimensions */
  --camera-width: 100%;
  --camera-height: 400px;
  
  /* Detection overlay colors */
  --detection-overlay-color: rgba(0, 123, 255, 0.3);
  --detection-border-color: #007bff;
  --detection-border-width: 2px;
  
  /* UI element colors */
  --button-background: #007bff;
  --button-text-color: #ffffff;
  --button-border-radius: 4px;
  
  /* Status indicator colors */
  --status-success-color: #28a745;
  --status-warning-color: #ffc107;
  --status-error-color: #dc3545;
}

Custom CSS Classes

You can style the component container and add custom overlays:

/* Component container styling */
.document-scanner-container {
  position: relative;
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
  background: #000;
}

/* Custom loading overlay */
.scanner-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 20px;
  border-radius: 8px;
  z-index: 1000;
}

/* Responsive design */
@media (max-width: 768px) {
  jaak-stamps {
    --camera-height: 300px;
  }
}

Theme Support

The component automatically adapts to system dark/light mode preferences:

/* Light theme (default) */
jaak-stamps {
  --background-color: #ffffff;
  --text-color: #333333;
  --border-color: #dddddd;
}

/* Dark theme */
@media (prefers-color-scheme: dark) {
  jaak-stamps {
    --background-color: #1a1a1a;
    --text-color: #ffffff;
    --border-color: #444444;
  }
}

Compatibility

Browser Support

  • Chrome/Edge: 80+
  • Firefox: 75+
  • Safari: 13+
  • iOS Safari: 13+
  • Chrome Android: 80+

Framework Compatibility

  • Vanilla JavaScript: Full support
  • React: 16.8+
  • Angular: 12+
  • Vue.js: 3+
  • Svelte: 3+

Required Dependencies

  • Modern browser with WebRTC support
  • Camera access permission
  • HTTPS context (required for camera access)

Optional Dependencies

  • Web Workers support for enhanced performance
  • WebAssembly support for AI model acceleration

Troubleshooting

Common Issues

Camera Not Working

Problem: Camera preview is black or not showing

Solutions:

// Check camera permissions
const scanner = document.querySelector('jaak-stamps');
const cameraInfo = await scanner.getCameraInfo();
console.log('Available cameras:', cameraInfo.availableCameras);

// Try switching cameras
await scanner.setPreferredCamera('back');

Slow Performance

Problem: Component is slow or laggy

Solutions:

// Preload the AI model
const scanner = document.querySelector('jaak-stamps');
await scanner.preloadModel();

// Reduce capture delay for faster response
await scanner.setCaptureDelay(1000);

// Disable debug mode in production
scanner.setAttribute('debug', 'false');

No Images Captured

Problem: Capture completes but no images returned

Solutions:

// Check component status
const status = await scanner.getStatus();
console.log('Component status:', status);

// Verify capture process completion
const isCompleted = await scanner.isProcessCompleted();
if (isCompleted) {
  const images = await scanner.getCapturedImages();
  console.log('Images:', images);
}

Memory Issues on Mobile

Problem: Component crashes on mobile devices

Solutions:

<!-- Reduce memory usage -->
<jaak-stamps
  mask-size="60"
  crop-margin="15"
  capture-delay="2000">
</jaak-stamps>

Frequently Asked Questions

Q: Can I use this component without HTTPS? A: No, camera access requires HTTPS in production. Use localhost for development.

Q: How do I handle multiple document types? A: Enable document classification:

<jaak-stamps use-document-classification="true"></jaak-stamps>

Q: Can I customize the detection area? A: Yes, use the mask-size property to adjust the detection frame size.

Q: Can I disable automatic document detection? A: Yes, set use-document-detector="false" to disable AI detection and enable manual capture mode:

<jaak-stamps use-document-detector="false"></jaak-stamps>

Q: How do I get only the cropped images? A: Access the cropped property from the captured images:

const images = await scanner.getCapturedImages();
const croppedFront = images.front.cropped; // Base64 string

Q: Is the component accessible? A: Yes, the component includes ARIA labels and keyboard navigation support.

Q: Can I use this in a Progressive Web App (PWA)? A: Yes, the component is fully compatible with PWAs and works offline after initial load.


License

MIT © Jaak AI