DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 966,904 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for React-Typescript user sign-up form using FaceIO for face authentication.
John Thiong'o
John Thiong'o

Posted on

React-Typescript user sign-up form using FaceIO for face authentication.

Hi there,

This is part of a two part series, where I am going to show you how to use React and Typescript coupled with FaceIO to sign-up, authenticate a user and consume user data in your website.

What is FaceIO.

FaceIO is a facial authentication framework to authenticate users via face recognition instead of the traditional login/password. It is implemented via a simple JavaScript snippet (like google tag). More here.

Why use FaceIO.

  1. The simplicity. We all know the complexity and work that goes into creating a way to authenticate users to your website yet all we want to do is to register a user and be able to login the user every time they came back.
    In comes FaceIO with the easiest way to add passwordless authentication to your web based application. As we go on you will see how easy it is leaving us with more time to create amazing user experiences.

  2. FaceIO does not add to the bundle size of your project. As we will see we just add a script to the index.html and you are done.

  3. It is compatible with pretty much every browser out there (Chrome, Firefox, Safari, Edge & Chromium derivatives).

Let me now demonstrate the simplicity of FaceIO by building this sign-up form.

Initializing React, Typescript and Tailwind CSS in our project using Vite.

Fire up you favorite code editor and open the bash terminal.

I am going to use yarn so,

yarn create vite

Image description

You can use yarn dev β€” host to host your project and be able to access it via multiple devices.

Let us add Tailwind CSS to our project.

yarn add -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Go into src/tailwind.config.cjs and replace the contents with.

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
Enter fullscreen mode Exit fullscreen mode

If you now run yarn dev

Image description

Now let me show you how easy it is to add FaceIO to your project.

Go to index.html , note the contents and then replace them with

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FaceIO authentication using react + ts</title>
  </head>
  <body>
    <script src="https://cdn.faceio.net/fio.js"></script>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html> 
Enter fullscreen mode Exit fullscreen mode

As you can see the only thing we have added is

<script src=”https://cdn.faceio.net/fio.js"></script>

above the <div id=”root”></div>

It is as simple as that. More on the integration here.

Before we begin implementing FaceIO in our project you will need to sign up on FaceIO console. Once you have signed up you will come to this page.

Image description

Select NEW FACEIO APPLICATION and follow the prompts.

Image description

Once done note the public Id.

Image description

Before we continue to creating our sign-up form component let us also bring in tailwind css.

Go to index.css and replace the contents with,

@tailwind base;
@tailwind components;
@tailwind utilities;

Enter fullscreen mode Exit fullscreen mode

Go to app.tsx and replace its contents with this,

function App() {

  return (
    <div className='min-h-screen flex justify-center'>
      <h1 className='text-3xl font-bold text-yellow-600'>
        FaceIO authentication using react and typescript
      </h1>
    </div>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

Your application should now look like this,

Image description

Let us now create a new folder named components and in it a file named SignupForm.tsx

Image description

We will use react hook form to create our form let us add it to our project.

yarn add react-hook-form @hookform/resolvers yup

Make the necessary imports in the SignupForm.tsx.

import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';


Enter fullscreen mode Exit fullscreen mode

Import the form into app.tsx file and make necessary changes,

Image description

Let us create the ui for form.

Under the h1 tags in SignupForm.tsx,

<form className='space-y-6'>
        <div>
          <label
            htmlFor=''
            className='text-sm font-bold backdrop:bold text-gray-600 block'
          >
            Name
          </label>
          <input
            type='text'
            placeholder='name'
            className='w-full p-2 border border-blue-900 rounded mt-1'
          />
        </div>
        <div>
          <label
            htmlFor=''
            className='text-sm font-bold backdrop:bold text-gray-600 block'
          >
            Email
          </label>
          <input
            type='text'
            placeholder='email@mail.com'
            className='w-full p-2 border border-blue-900 rounded mt-1'
          />
        </div>
        <div>
          <button className='w-full py-2 px-4 bg-blue-700 rounded-md text-white text-sm'>
            Sign Up
          </button>
        </div>
</form>
Enter fullscreen mode Exit fullscreen mode

Now for the fun part of adding the logic, first let us create a new folder in the folder src with a file to store our types which we are going to use through out our build let us call it ,

/** src/@types/user.d.ts */

interface Iuser {
  name: string;
  email: string;
}
Enter fullscreen mode Exit fullscreen mode

Back to our form let us define the data that we are going to take from the user and submit to faceIO to register the said user using yup. This should be done above the SignupForm declaration. This will also enable us to alert the user if any errors occur.

const SignupSchema = yup
  .object({
    name: yup.string().required(),
    email: yup.string().required(),
  })
  .required();
Enter fullscreen mode Exit fullscreen mode

Inside the SignupForm function let us use the useForm from react-hook-form. It provides us with some handy functions that will help us to take input from the user and deliver it where we need like, register, handleSubmit and errors, as shown below.

const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<Iuser>({
    resolver: yupResolver(SignupSchema),
  });
Enter fullscreen mode Exit fullscreen mode

Let us also create a onSubmit function that will enable us to submit the data we take from the user to FaceIO.

const onSubmit = (data: Iuser) => {
    alert(JSON.stringify(data));
handleSignUp(data);
  };
Enter fullscreen mode Exit fullscreen mode

As you can see inside there is a handleSignUp function let us define it but before we do that let us load FaceIO into our page using a useEffect hook, make the necessary import of useEffect then,

let faceio: any;
  useEffect(() => {
    faceio = new faceIO('fioxxxxxx');
  }, []);
Enter fullscreen mode Exit fullscreen mode

Note the β€˜fioxxxxx’ you should ensure that you have replaced it with your FaceIO public id.

Let us now create the handleSignUp function

const handleSignUp = async (user: Iuser): Promise<any> => {
    try {
      let response: any = await faceio.enroll({
        locale: 'auto',
        payload: {
          name: `${user.name}`,
          email: `${user.email}`,
        },
      });
      alert(
        ` Unique Facial ID: ${response.facialId}
      Enrollment Date: ${response.timestamp}
      Gender: ${response.details.gender}
      Age Approximation: ${response.details.age}
      payload: ${JSON.stringify(response.details)}`
      );
    } catch (error) {
      alert('Unable to register you please refresh page and try again');
    }
  };
Enter fullscreen mode Exit fullscreen mode

As you can see in it we have a try-catch block where in the try block we call a FaceIO function called enroll which takes a payload containing the name of the user and email which we will attain from the form. For more of the enroll function, check this documentation.

Let us now update the form tags to now be able to take in the user data and submit it.

<form className='space-y-6' onSubmit={handleSubmit(onSubmit)}>
//....
<form/>
Enter fullscreen mode Exit fullscreen mode

And the input fields,

<input 
            type='text'
            placeholder='name'
            {...register('name')}
            className='w-full p-2 border border-blue-900 rounded mt-1'
          />
          {errors.name && <p className='text-red-900'>{errors.name.message}</p>}
//email input
<input
            type='text'
            placeholder='email@mail.com'
            {...register('email')}
            className='w-full p-2 border border-blue-900 rounded mt-1'
          />
          {errors.email && (
            <p className='text-red-900'>{errors.email.message}</p>
          )}
Enter fullscreen mode Exit fullscreen mode

And with that we are done the whole sign up form looks like,

import React, { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
const SignupSchema = yup
  .object({
    name: yup.string().required(),
    email: yup.string().required(),
  })
  .required();
const SignupForm = () => {
  let faceio: any;
  useEffect(() => {
    faceio = new faceIO('fioa48b7');
  }, []);
const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<Iuser>({
    resolver: yupResolver(SignupSchema),
  });
//create  a submit function that will submit the data
  const onSubmit = (data: Iuser) => {
    alert(JSON.stringify(data));
handleSignUp(data);
  };
//create a signup function that will submit the data to faceIO by calling the function faceIO enroll
  const handleSignUp = async (user: Iuser): Promise<any> => {
    try {
      let response: any = await faceio.enroll({
        locale: 'auto',
        payload: {
          name: `${user.name}`,
          email: `${user.email}`,
        },
      });
      alert(
        ` Unique Facial ID: ${response.facialId}
      Enrollment Date: ${response.timestamp}
      Gender: ${response.details.gender}
      Age Approximation: ${response.details.age}
      payload: ${JSON.stringify(response.details)}`
      );
    } catch (error) {
      alert('Unable to register you please refresh page and try again');
    }
  };
return (
    <div className='max-w-md mx-auto mt-4 bg-yellow-100 p-8 border border-gray-3000'>
      <h1 className='text-3xl font-bold text-blue-600 pb-5'>
        Sign-up form using FaceIO
      </h1>
<form className='space-y-6' onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label
            htmlFor=''
            className='text-sm font-bold backdrop:bold text-gray-600 block'
          >
            Name
          </label>
          <input
            type='text'
            placeholder='name'
            {...register('name')}
            className='w-full p-2 border border-blue-900 rounded mt-1'
          />
          {errors.name && <p className='text-red-900'>{errors.name.message}</p>}
        </div>
        <div>
          <label
            htmlFor=''
            className='text-sm font-bold backdrop:bold text-gray-600 block'
          >
            Email
          </label>
          <input
            type='text'
            placeholder='email@mail.com'
            {...register('email')}
            className='w-full p-2 border border-blue-900 rounded mt-1'
          />
          {errors.email && (
            <p className='text-red-900'>{errors.email.message}</p>
          )}
        </div>
        <div>
          <button className='w-full py-2 px-4 bg-blue-700 rounded-md text-white text-sm'>
            Sign Up
          </button>
        </div>
      </form>
    </div>
  );
};
export default SignupForm;
Enter fullscreen mode Exit fullscreen mode

This should be the finished product.

Image description

In case of errors while inputting the form data.

Image description

If everything is ok.

Image description

If you have loved this add a star to it over in GitHub.

For more on FaceIO.

  1. The getting started guide.
  2. The integration guide.
  3. The Developer center.
  4. The frequently asked questions section.
  5. The trust center.

There are also some very interesting articles to get you on your way.

Login/Sign up form using FaceIO, Next.js and Tailwind CSS

Implementing facial authentication on a Vue.js app.

How to Authenticate a User with Face Recognition in React.js.

That is the conclusion for now but part two is here, but always check in this space for more.

Top comments (0)

🌚 Life is too short to browse without dark mode