@fortt/react
v0.0.6
Published
Fortt React SDK - Lightweight TypeScript SDK for React and Next.js apps
Maintainers
Readme
Fortt React SDK
Lightweight TypeScript SDK for integrating React and Next.js apps with Fortt's public verification endpoint.
Installation
npm install fortt/react
# or
yarn add fortt/react
# or
pnpm add fortt/reactQuick Start
React SPA
import { ForttProvider, useFortt } from 'fortt/react';
function LoginForm() {
const { verifyAndRun, state, error, challengeUI } = useFortt();
const handleLogin = async () => {
await verifyAndRun(
async () => {
// Your login logic here
console.log('Login successful!');
},
{
source: 'login',
visitorId: 'visitor_123',
sessionId: 'session_456',
}
);
};
return (
<div>
<button onClick={handleLogin} disabled={state === 'verifying'}>
{state === 'verifying' ? 'Verifying...' : 'Login'}
</button>
{challengeUI}
{error && <div>Error: {error.message}</div>}
</div>
);
}
function App() {
return (
<ForttProvider projectId="proj_your_project_id">
<LoginForm />
</ForttProvider>
);
}Next.js App Router
Client Component:
'use client';
import { ForttProvider, useFortt } from 'fortt/react';Server API Route:
import { verifyServer } from 'fortt/react/server';
export async function POST(request: Request) {
const response = await verifyServer({
projectId: process.env.FORTT_PROJECT_ID!,
body: {
source: 'login',
},
});
// Handle response...
}API Reference
<ForttProvider />
React Context Provider that configures the SDK.
Props:
projectId(string, required): Your Fortt project IDapiBaseUrl(string, optional): API base URL (default:https://sentinel-backend.fly.dev)proxyVerifyPath(string, optional): Proxy path for verification requestsdefaultSource(string, optional): Default source for verification requestschildren(ReactNode, required): Your app components
useFortt()
React hook for verification.
Returns:
verifyAndRun(fn, args?): Function to verify and run a callbackstate: Current state ('idle' | 'verifying' | 'challenged')error: Error object if verification failedchallengeUI: React node for challenge UI (if challenged)challengeData: Challenge data object (if challenged)
Example:
const { verifyAndRun, state, challengeUI } = useFortt();
await verifyAndRun(
async () => {
// Your protected action
},
{
source: 'login',
visitorId: 'visitor_123',
sessionId: 'session_456',
deviceId: 'device_789',
nonce: 'unique_nonce',
forceChallenge: false,
debug: false,
}
);<ForttChallenge />
Component that renders challenge UI in an iframe.
Props:
url(string, required): Challenge URLrequestId(string, required): Request IDpollIntervalMs(number, optional): Polling interval (0 = disabled)pollTimeoutMs(number, optional): Polling timeout (default: 120000)onLoaded(function, optional): Called when challenge loadsonSolved(function, optional): Called when challenge is solvedonExpired(function, optional): Called when challenge expiresonError(function, optional): Called on error
verify(options)
Low-level browser verification function.
Example:
import { verify } from 'fortt/react';
const response = await verify({
projectId: 'proj_abc123',
body: {
source: 'login',
visitorId: 'visitor_123',
},
debug: true,
});verifyServer(args)
Server-side verification function.
Example:
import { verifyServer } from 'fortt/react/server';
const response = await verifyServer({
projectId: 'proj_abc123',
baseUrl: 'https://sentinel-backend.fly.dev',
body: {
source: 'login',
},
debug: false,
});Types
All TypeScript types are exported:
import type {
VerifyResponse,
VerifyRequest,
Decision,
Challenge,
SignalResult,
RiskBand,
ActionType,
// ... and more
} from 'fortt/react';Error Handling
The SDK throws ForttError (browser) or ForttServerError (server) for errors:
import { ForttError } from 'fortt/react';
try {
await verify({ ... });
} catch (error) {
if (error instanceof ForttError) {
console.error('Code:', error.code);
console.error('Status:', error.statusCode);
}
}Proxy Path
To proxy requests through your backend:
<ForttProvider
projectId="proj_your_project_id"
proxyVerifyPath="/api/fortt/verify"
>
{/* Your app */}
</ForttProvider>License
ISC
