🎉 @facesmash/sdk v0.1.0 is now available on npm — Read the docs →
FaceSmash Docs
Guides

React Integration

Add face login to a React application step by step

Overview

This guide walks you through adding FaceSmash face authentication to an existing React application. By the end, you'll have a working face login and registration flow.

Step 1: Install the SDK

npm install @facesmash/sdk

React bindings are included in the @facesmash/sdk/react entry point. React 17+ is required.

Step 2: Add the Provider

Wrap your app (or the section that uses face auth) with FaceSmashProvider:

// src/App.tsx
import { FaceSmashProvider } from '@facesmash/sdk/react';

function App() {
  return (
    <FaceSmashProvider
      config={{ apiUrl: 'https://api.facesmash.app' }}
      onReady={() => console.log('Models loaded')}
      onError={(err) => console.error('Model loading failed:', err)}
    >
      <Router>
        <Route path="/login" element={<LoginPage />} />
        <Route path="/register" element={<RegisterPage />} />
        <Route path="/dashboard" element={<Dashboard />} />
      </Router>
    </FaceSmashProvider>
  );
}

The provider handles:

  • Loading TensorFlow.js and face detection models
  • Initializing the WebGL backend
  • Providing the SDK client to child components via context

Step 3: Add Face Login

// src/pages/LoginPage.tsx
import { FaceLogin } from '@facesmash/sdk/react';
import { useNavigate } from 'react-router-dom';

function LoginPage() {
  const navigate = useNavigate();

  return (
    <div className="max-w-md mx-auto mt-20">
      <h1 className="text-2xl font-bold mb-6">Sign In</h1>
      <FaceLogin
        onResult={(result) => {
          if (result.success) {
            localStorage.setItem('user', JSON.stringify(result.user));
            navigate('/dashboard');
          } else {
            alert(result.error || 'Face not recognized.');
          }
        }}
        className="w-full h-80 rounded-xl overflow-hidden"
      />
    </div>
  );
}

Step 4: Add Face Registration

// src/pages/RegisterPage.tsx
import { useState } from 'react';
import { FaceRegister } from '@facesmash/sdk/react';
import { useNavigate } from 'react-router-dom';

function RegisterPage() {
  const navigate = useNavigate();
  const [name, setName] = useState('');

  return (
    <div className="max-w-md mx-auto mt-20">
      <h1 className="text-2xl font-bold mb-6">Register</h1>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Your name"
        className="w-full p-3 mb-4 border rounded-lg"
      />
      {name && (
        <FaceRegister
          name={name}
          onResult={(result) => {
            if (result.success) {
              alert(`Welcome, ${result.user.name}!`);
              navigate('/login');
            } else {
              alert(result.error || 'Registration failed.');
            }
          }}
          className="w-full h-80 rounded-xl overflow-hidden"
        />
      )}
    </div>
  );
}

Step 5: Use Hooks for Custom Logic

For more control, use the programmatic hooks instead of the drop-in components:

// src/pages/CustomLoginPage.tsx
import { useFaceSmash, useFaceLogin } from '@facesmash/sdk/react';
import { useNavigate } from 'react-router-dom';

function CustomLoginPage() {
  const navigate = useNavigate();
  const { isReady, isLoading, error: initError } = useFaceSmash();
  const { login, isScanning, result, reset } = useFaceLogin();

  // You handle the camera and image capture yourself
  const handleCapture = async (images: string[]) => {
    const loginResult = await login(images);
    if (loginResult.success) {
      localStorage.setItem('user', JSON.stringify(loginResult.user));
      navigate('/dashboard');
    }
  };

  if (isLoading) return <p>Loading face recognition models...</p>;
  if (initError) return <p>Error: {initError}</p>;
  if (!isReady) return <p>Initializing...</p>;

  return (
    <div>
      {/* Your custom camera UI here */}
      {isScanning && <p>Scanning...</p>}
      {result && !result.success && <p>Error: {result.error}</p>}
    </div>
  );
}

Customizing the UI

Custom Overlay

Pass any React content as an overlay on top of the video feed:

<FaceLogin
  onResult={handleResult}
  className="w-full h-80 rounded-xl overflow-hidden"
  overlay={
    <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
      <div className="w-48 h-48 border-2 border-green-500 rounded-full" />
    </div>
  }
/>

Custom Loading and Error States

<FaceLogin
  onResult={handleResult}
  loadingContent={
    <div className="flex items-center justify-center h-80">
      <p>Loading face recognition...</p>
    </div>
  }
  errorContent={(error, retry) => (
    <div className="flex flex-col items-center justify-center h-80 gap-4">
      <p className="text-red-500">{error}</p>
      <button onClick={retry} className="px-4 py-2 bg-blue-500 text-white rounded">
        Retry
      </button>
    </div>
  )}
/>

Event Listening

Listen to all SDK events via the provider:

<FaceSmashProvider
  config={{ apiUrl: 'https://api.facesmash.app' }}
  onEvent={(event) => {
    switch (event.type) {
      case 'models-loading':
        console.log(`Loading: ${event.progress}%`);
        break;
      case 'login-success':
        console.log('Matched:', event.user.name, event.similarity);
        break;
      case 'login-failed':
        console.log('Failed:', event.error);
        break;
    }
  }}
>

On this page