This guide walks you through integrating OneSDK with Next.js, providing you with a solid foundation for building secure and efficient KYC workflows.

Quick Start Video

Setup Instructions

1

Create Next.js Project

$npx create-next-app@latest my-next-app
>cd my-next-app
2

Install Dependencies

$npm install
>npm install @frankieone/one-sdk
3

Configure Environment

Create a .env.local file with your OneSDK credentials:

1NEXT_PUBLIC_CUSTOMER_ID=your_customer_id
2NEXT_PUBLIC_API_KEY=your_api_key
3NEXT_PUBLIC_CHILD_ID=your_child_id # Optional

Implementation Guide

Create a new file hooks/useOneSDK.js:

1"use client";
2import OneSdk from "@frankieone/one-sdk";
3import { useEffect, useRef, useState } from "react";
4
5const useOneSDK = ({ config }) => {
6 const [oneSDKInstance, setOneSDKInstance] = useState(null);
7 const [error, setError] = useState(null);
8 const [loading, setLoading] = useState(false);
9 const initializedRef = useRef(false);
10
11 const generateToken = async () => {
12 try {
13 const credentials = btoa(
14 `${process.env.NEXT_PUBLIC_CUSTOMER_ID}:${process.env.NEXT_PUBLIC_API_KEY}`
15 );
16
17 const response = await fetch(
18 "https://backend.latest.frankiefinancial.io/auth/v2/machine-session",
19 {
20 method: "POST",
21 headers: {
22 authorization: `machine ${credentials}`,
23 "Content-Type": "application/json",
24 },
25 body: JSON.stringify({
26 permissions: {
27 preset: "one-sdk",
28 reference: `demo-${new Date().toISOString()}`,
29 },
30 }),
31 }
32 );
33
34 return await response.json();
35 } catch (error) {
36 setError(error.message);
37 return null;
38 }
39 };
40
41 const initializeSDK = async () => {
42 setLoading(true);
43 try {
44 const token = await generateToken();
45 if (!token) return;
46
47 const instance = await OneSdk({
48 session: token,
49 ...config,
50 });
51
52 setOneSDKInstance(instance);
53 } catch (error) {
54 setError(error.message);
55 } finally {
56 setLoading(false);
57 }
58 };
59
60 useEffect(() => {
61 if (!initializedRef.current) {
62 initializeSDK();
63 initializedRef.current = true;
64 }
65 }, [config]);
66
67 return { oneSDKInstance, error, loading };
68};
69
70export default useOneSDK;

Create a new component file components/EndToEnd.js:

1"use client";
2import { useEffect } from "react";
3import useOneSDK from "../hooks/useOneSDK";
4
5const EndToEnd = () => {
6 const config = {
7 mode: "development",
8 recipe: {
9 form: {
10 provider: {
11 name: "react",
12 },
13 },
14 },
15 };
16
17 const { oneSDKInstance, error, loading } = useOneSdk({ config });
18
19 const initializeComponents = () => {
20 if (!oneSDKInstance) return;
21
22 // Initialize Components
23 const components = {
24 welcome: oneSDKInstance.component("form", {
25 name: "WELCOME",
26 type: "manual",
27 }),
28 consent: oneSDKInstance.component("form", {
29 name: "CONSENT"
30 }),
31 document: oneSDKInstance.component("form", {
32 name: "DOCUMENT",
33 showPreps: true,
34 }),
35 biometrics: oneSDKInstance.component("biometrics"),
36 };
37
38 // Mount Welcome Component
39 components.welcome.mount("#form-container");
40
41 // Setup Event Handlers
42 setupEventHandlers(components);
43 };
44
45 const setupEventHandlers = (components) => {
46 const { welcome, consent, document, biometrics } = components;
47
48 welcome.on("form:welcome:ready", () => {
49 consent.mount("#form-container");
50 });
51
52 consent.on("form:consent:ready", () => {
53 document.mount("#form-container");
54 });
55
56 // Add more event handlers as needed
57 };
58
59 useEffect(() => {
60 if (oneSDKInstance) {
61 initializeComponents();
62 }
63 }, [oneSDKInstance]);
64
65 if (loading) {
66 return <div>Loading OneSDK...</div>;
67 }
68
69 if (error) {
70 return <div>Error: {error}</div>;
71 }
72
73 return <div id="form-container" />;
74};
75
76export default EndToEnd;

Update your page file (e.g., app/page.js):

1import EndToEnd from '../components/EndToEnd';
2
3export default function Home() {
4 return (
5 <main>
6 <EndToEnd />
7 </main>
8 );
9}

Component Configuration

1const welcome = oneSDKInstance.component("form", {
2 name: "WELCOME",
3 type: "manual",
4 descriptions: [
5 { label: 'Welcome to our KYC process', style: {} },
6 { label: 'Please follow the steps to verify your identity', style: {} },
7 ],
8});

Event Handling

1// Welcome Form Events
2welcome.on("form:welcome:ready", () => {
3 // Handle welcome form ready
4});
5
6welcome.on("form:welcome:failed", () => {
7 // Handle welcome form failure
8});
9
10// Document Form Events
11document.on("form:document:ready", async ({ inputInfo }) => {
12 // Handle document form ready
13 const docType = inputInfo.documentType;
14 // Initialize OCR component
15});
1biometrics.on("detection_failed", () => {
2 // Handle failed detection
3});
4
5biometrics.on("processing", () => {
6 // Handle processing state
7});
8
9biometrics.on("results", (result) => {
10 // Handle biometrics results
11});

Best Practices

Error Handling

Always implement proper error handling for both SDK initialization and component events.

Loading States

Show appropriate loading states during initialization and between component transitions.

Event Cleanup

Properly clean up event listeners when components unmount to prevent memory leaks.

Security

Never expose credentials in client-side code. Use environment variables and server-side token generation.

Remember to handle cleanup in your components by implementing proper unmounting logic and removing event listeners when components are destroyed.

Troubleshooting

  • SDK Initialization Failed: Check your credentials and network connection
  • Component Mount Errors: Ensure the container element exists in the DOM
  • Event Handler Issues: Verify event names and handler implementations
1// Enable debug logging
2const config = {
3 mode: "development",
4 debug: true,
5 // ... other config options
6};
7
8// Listen to all events
9oneSDKInstance.on("*", (event) => {
10 console.log("Event:", event);
11});
Built with