Extended Onboarding React Integration

How to Create an App Using Incode Standard Flow with React 18

This guide will teach you how to create an app using the Incode Standard Flow with React 18. You can call this approach a "linear flow" where all Incode modules are executed one after another step-by-step.

This approach is ideal for scenarios where you want your users to go through the Incode modules before they proceed further in your application.

Before Getting Started

Ensure you have read the following guides:

Step 1: Setup your TS project

For this React guide, we are going to start our project using Vite and TypeScript. Please ensure your development environment is ready with NodeJs version 18 or more and run the following commands:

npm create vite@latest my-react-app -- --template react-ts
cd my-react-app
npm install

Setting Up HTTPS on the Frontend Local Server

To enable HTTPS in Vite, install vite-plugin-mkcert to create SSL certificates locally and automatically.

Install mkcert plugin:

npm install vite-plugin-mkcert

Modify your vite.config.ts file:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import mkcert from 'vite-plugin-mkcert'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), mkcert()],
  server: { https: true, host: true },
})

In your package.json, modify the dev script:

"dev": "vite --host",

Run your script again with npm run dev, and you will see:

  VITE v5.0.7  ready in 114 ms

➜  Local:   http://localhost:5173/
  ➜  Network: https://192.168.68.103:5173/

Add the network value to your .env file:

VITE_LOCAL_SERVER_URL=https://192.168.68.103:5173/

Step 2: Initialize Incode's Web SDK

First, install @incodetech/welcome in your project:

npm install @incodetech/welcome

Create an incode.ts file in /src:

import { create } from "@incodetech/welcome";
const apiURL = import.meta.env.VITE_INCODE_API_URL as string;

type SessionType = {
  token: string,
  uniqueId?: string
};

const incode = create({
  apiURL: apiURL
});

export { incode, type SessionType };

Add the following variable to the .env file:

VITE_INCODE_API_URL=https://demo-api.incodesmile.com/0/

Step 3: Get Incode's Session Object

A session object includes an access token which is used to authenticate requests to your Incode environment.

To complete this step, please set up and run a sample server. The server will fetch an access token using the /start endpoint. You can set up a sample server using the instructions here: Quick Start Sample Servers.

Establish a reverse proxy in your vite.config.ts:

  server: {
    https: true,
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        secure: false,
        ws: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      }
    }
  },

Update your .env file:

VITE_INCODE_API_URL=https://demo-api.incodesmile.com/0/
VITE_INCODE_CLIENT_ID=<your-client-id>
VITE_TOKEN_SERVER_URL=/api

Modify your App.tsx file to fetch the token:

import { useState, useEffect, useRef } from 'react';

async function startOnboardingSession() {
  const tokenServerURL = import.meta.env.VITE_TOKEN_SERVER_URL as string;

const urlParams = new URLSearchParams(window.location.search);
  const uniqueId = urlParams.get('uniqueId');

let sessionStartUrl = `${tokenServerURL}/start`;
  if (uniqueId) sessionStartUrl += `?uniqueId=${uniqueId}`;

const response = await fetch(sessionStartUrl);
  if (!response.ok) {
    const sessionData = await response.json();
    throw new Error(sessionData.error);
  }

return await response.json() as SessionType;
}

function App() {
  const [session, setSession] = useState(null);
  const isLoaded = useRef(false);

useEffect(() => {
    if (isLoaded.current) return;

startOnboardingSession().then(async (session) => {
      setSession(session);
    }).catch(
      (e) => console.log(e)
    );
    isLoaded.current = true;
  }, []);

if (!session) return (<p>Loading Session...</p>);
  return (<pre>{JSON.stringify(session, null, 2)}</pre>);
}

export default App;

Step 4: Add the Render Step Utility

To handle the onboarding steps, let's create a Steps.tsx file in /src/components:

import { Children, cloneElement } from "react";

function Steps({ children, currentStep }: StepsPropTypes) {
  return (
    <>
      {Children.map(
        children,
        (child, index) => currentStep === index && cloneElement(child)
      )}
    </>
  );
}

type StepsPropTypes= {
  children: React.ReactElement[];
  currentStep: number;
};
export default Steps;

Step Component Example:

import Steps from "./Steps";
function App() {
  const [step, setStep] = useState(0);

function goNext() {
    setStep(step + 1);
  }

return (
    <Steps currentStep={step}>
      <h1 onClick={() => goNext()}>Step 1</h1>
      <h1 onClick={() => goNext()}>Step 2</h1>
      <h1 onClick={() => goNext()}>Step 3</h1>
      <h1 onClick={() => goNext()}>Step 4</h1>
      <h1>Last Step</h1>
    </Steps>
  );
}

Following Steps

You can follow similar patterns for the rest of the setup, including redirecting to mobile, user consent, and capturing IDs using the components created in each section.

Running Your App

Run the app by executing:

npm run dev

Take notice of the Network value you will access on your mobile device.

References