# 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:
- [Getting Started with Incode Web SDK](https://developer.incode.com/docs/single-onboarding)
- [Using Onboarding sessions with the Web SDK](https://developer.incode.com/docs/single-onboarding)

## 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](https://nodejs.org/en) and run the following commands:

```shell
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:
```shell
npm install vite-plugin-mkcert
```

Modify your `vite.config.ts` file:
```javascript
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:
```json
"dev": "vite --host",
```

Run your script again with `npm run dev`, and you will see:
```json
  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:
```text
VITE_LOCAL_SERVER_URL=https://192.168.68.103:5173/
```

## Step 2: Initialize Incode's Web SDK
First, install `@incodetech/welcome` in your project:
```shell
npm install @incodetech/welcome
```

Create an `incode.ts` file in `/src`:
```typescript
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:
```text
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](https://developer.incode.com/docs/quick-start-servers).

Establish a reverse proxy in your `vite.config.ts`:
```typescript
  server: {
    https: true,
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        secure: false,
        ws: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      }
    }
  },
```

Update your `.env` file:
```text
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:
```typescript
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`: 
```typescript
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:
```jsx
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:
```shell
npm run dev
```

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

## References
- This guide is based on the [Diagram for the Incode Web SDK - Standard Integration Approach.](https://developer.incode.com/docs/single-onboarding)
- You can visit the [Incode WebSDK reference](https://developer.incode.com/docs/web-sdk-reference) for more details on the methods used in this guide.
