@insforge/react 1.1.4 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,718 +1,718 @@
1
- # @insforge/react
2
-
3
- **Framework-agnostic authentication solution for React applications.** Production-ready components with full business logic included.
4
-
5
- > **✨ CSS-in-JS**: All components now use Emotion CSS-in-JS for zero FOUC in SSR environments. No CSS imports needed!
6
-
7
- ## Why @insforge/react?
8
-
9
- ✅ **Framework Agnostic** - Works with any React setup (Vite, CRA, or no bundler)
10
- ✅ **Zero Router Dependencies** - Built-in navigation abstraction works with any routing solution
11
- ✅ **Route Protection** - Built-in `RouteGuard` for vanilla React apps
12
- ✅ **Production Ready** - Complete auth flows with business logic included
13
- ✅ **Full TypeScript** - Complete type safety out of the box
14
-
15
- ---
16
-
17
- ## Quick Start
18
-
19
- Get authentication working in your React app in 5 minutes.
20
-
21
- ### 1. Install
22
-
23
- ```bash
24
- npm install @insforge/react
25
- # or
26
- yarn add @insforge/react
27
- # or
28
- pnpm add @insforge/react
29
- ```
30
-
31
- #### Environment Variables
32
-
33
- ```bash
34
- # .env
35
- VITE_INSFORGE_BASE_URL=https://your-project.insforge.app/
36
- ```
37
-
38
- ### 2. Setup Provider & Route Guard
39
-
40
- Wrap your app with `InsforgeProvider`:
41
-
42
- ```tsx
43
- // src/main.tsx (Vite) or src/index.tsx (CRA)
44
- import { StrictMode } from 'react';
45
- import { createRoot } from 'react-dom/client';
46
- import { InsforgeProvider } from '@insforge/react';
47
- import App from './App';
48
-
49
- createRoot(document.getElementById('root')!).render(
50
- <StrictMode>
51
- <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
52
- <App />
53
- </InsforgeProvider>
54
- </StrictMode>
55
- );
56
- ```
57
-
58
- ### 3. Use Components & Hooks
59
-
60
- Now you can use authentication components and hooks anywhere in your app:
61
-
62
- ```tsx
63
- // src/App.tsx
64
- import { SignInButton, SignUpButton, SignedIn, SignedOut, UserButton } from '@insforge/react';
65
-
66
- export default function App() {
67
- return (
68
- <div>
69
- <SignedOut>
70
- <SignInButton />
71
- <SignUpButton />
72
- </SignedOut>
73
-
74
- <SignedIn>
75
- <nav>
76
- <UserButton />
77
- </nav>
78
- <h1>Welcome to your dashboard!</h1>
79
- </SignedIn>
80
- </div>
81
- );
82
- }
83
- ```
84
-
85
- **That's it!** 🎉 Your app is now protected with authentication.
86
-
87
- ---
88
-
89
- ## Usage Patterns
90
-
91
- ### Option 1: Pre-built Components (Fastest)
92
-
93
- Use complete auth flows with built-in UI and logic:
94
-
95
- ```tsx
96
- import { SignIn, SignUp, ForgotPassword, ResetPassword } from '@insforge/react';
97
-
98
- // In your app
99
- <SignIn /> // Complete sign-in flow
100
- <SignUp /> // Complete sign-up flow with email verification
101
- <ForgotPassword /> // Password reset request + verification
102
- <ResetPassword /> // Reset password with token (from URL params)
103
- ```
104
-
105
- ### Option 2: Form Components (UI Only)
106
-
107
- Use UI components and add your own logic:
108
-
109
- ```tsx
110
- import { SignInForm, useAuth } from '@insforge/react';
111
- import { useState } from 'react';
112
-
113
- function CustomSignIn() {
114
- const { signIn } = useAuth();
115
- const [email, setEmail] = useState('');
116
- const [password, setPassword] = useState('');
117
- const [error, setError] = useState('');
118
- const [loading, setLoading] = useState(false);
119
-
120
- const handleSubmit = async (e) => {
121
- e.preventDefault();
122
- setLoading(true);
123
- const result = await signIn(email, password);
124
- if ('error' in result) {
125
- setError(result.error);
126
- }
127
- setLoading(false);
128
- };
129
-
130
- return (
131
- <SignInForm
132
- email={email}
133
- password={password}
134
- onEmailChange={setEmail}
135
- onPasswordChange={setPassword}
136
- onSubmit={handleSubmit}
137
- error={error}
138
- loading={loading}
139
- />
140
- );
141
- }
142
- ```
143
-
144
- ### Option 3: Hooks Only (Headless)
145
-
146
- Build completely custom UI using authentication hooks:
147
-
148
- ```tsx
149
- import { useAuth } from '@insforge/react';
150
-
151
- function CustomAuthForm() {
152
- const { signIn, signUp, isLoaded } = useAuth();
153
-
154
- const handleLogin = async (email: string, password: string) => {
155
- const result = await signIn(email, password);
156
- if ('error' in result) {
157
- console.error(result.error);
158
- } else {
159
- console.log('Signed in!');
160
- }
161
- };
162
-
163
- return <form>...your custom UI...</form>;
164
- }
165
- ```
166
-
167
- ---
168
-
169
- ## Core Features
170
-
171
- ### Components
172
-
173
- **Pre-built with Business Logic:**
174
-
175
- - `<SignIn />` - Complete sign-in with email/password & OAuth
176
- - `<SignUp />` - Registration with password validation & email verification
177
- - `<ForgotPassword />` - Request password reset with email validation
178
- - `<ResetPassword />` - Reset password with token validation
179
- - `<VerifyEmail />` - Verify email with automatic token handling
180
- - `<UserButton />` - User dropdown with sign-out
181
- - `<RouteGuard />` - **NEW:** App-level route protection for vanilla React
182
- - `<Protect />` - Component-level protection wrapper
183
- - `<SignedIn>` / `<SignedOut>` - Conditional rendering
184
-
185
- **Form Components (Pure UI):**
186
-
187
- - `<SignInForm />` - Sign-in UI without logic
188
- - `<SignUpForm />` - Sign-up UI without logic
189
- - `<ForgotPasswordForm />` - Password reset request UI
190
- - `<ResetPasswordForm />` - Password reset with token UI
191
- - `<VerifyEmailStatus />` - Email verification status UI
192
-
193
- **Atomic Components (14 total):**
194
-
195
- - `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, `<AuthEmailVerificationStep />`, etc.
196
-
197
- ### Hooks
198
-
199
- ```tsx
200
- // Authentication state and methods
201
- const {
202
- signIn,
203
- signUp,
204
- signOut,
205
- isSignedIn,
206
- isLoaded,
207
- baseUrl, // From provider
208
- afterSignInUrl, // From provider
209
- } = useAuth();
210
-
211
- // Or use useInsforge (same as useAuth)
212
- const context = useInsforge();
213
-
214
- // User information
215
- const { user, updateUser, isLoaded } = useUser();
216
-
217
- // Public auth configuration (OAuth providers, password requirements, etc.)
218
- const { oauthProviders, authConfig, isLoaded } = usePublicAuthConfig();
219
- ```
220
-
221
- ---
222
-
223
- ## Customization
224
-
225
- ### Text Customization
226
-
227
- All components support full text customization:
228
-
229
- ```tsx
230
- <SignIn
231
- title="Welcome Back!"
232
- subtitle="We're happy to see you again"
233
- emailLabel="Your Email Address"
234
- emailPlaceholder="you@company.com"
235
- passwordLabel="Your Password"
236
- submitButtonText="Login Now"
237
- loadingButtonText="Signing you in..."
238
- signUpText="New to our platform?"
239
- signUpLinkText="Create an account"
240
- dividerText="or continue with"
241
- />
242
-
243
- <ForgotPassword
244
- title="Reset Your Password"
245
- subtitle="Enter your email to receive a reset code"
246
- emailLabel="Email Address"
247
- submitButtonText="Send Reset Code"
248
- backToSignInText="Remember your password?"
249
- successTitle="Check Your Email"
250
- successMessage="We've sent a reset code to your inbox"
251
- />
252
- ```
253
-
254
- ---
255
-
256
- ## Advanced Usage
257
-
258
- ### Conditional Rendering
259
-
260
- Control what users see based on auth state:
261
-
262
- ```tsx
263
- import { SignedIn, SignedOut, Protect } from '@insforge/react';
264
-
265
- function App() {
266
- return (
267
- <>
268
- <SignedOut>
269
- <SignIn />
270
- </SignedOut>
271
-
272
- <SignedIn>
273
- <Dashboard />
274
- </SignedIn>
275
-
276
- {/* Or use Protect for specific sections */}
277
- <Protect redirectTo="/sign-in">
278
- <ProtectedContent />
279
- </Protect>
280
- </>
281
- );
282
- }
283
- ```
284
-
285
- ### Build from Atomic Components
286
-
287
- ```tsx
288
- import {
289
- AuthContainer,
290
- AuthHeader,
291
- AuthFormField,
292
- AuthPasswordField,
293
- AuthSubmitButton,
294
- AuthErrorBanner,
295
- AuthDivider,
296
- AuthOAuthProviders,
297
- AuthLink,
298
- } from '@insforge/react';
299
-
300
- function CompletelyCustomAuth() {
301
- return (
302
- <AuthContainer>
303
- <AuthHeader title="Welcome to MyApp" subtitle="Sign in to continue" />
304
-
305
- <AuthErrorBanner error={error} />
306
-
307
- <form onSubmit={handleSubmit}>
308
- <AuthFormField
309
- id="email"
310
- type="email"
311
- label="Email"
312
- value={email}
313
- onChange={(e) => setEmail(e.target.value)}
314
- />
315
-
316
- <AuthPasswordField
317
- id="password"
318
- label="Password"
319
- value={password}
320
- onChange={(e) => setPassword(e.target.value)}
321
- authConfig={config}
322
- showStrengthIndicator
323
- />
324
-
325
- <AuthSubmitButton isLoading={loading}>Sign In</AuthSubmitButton>
326
- </form>
327
-
328
- <AuthDivider text="or" />
329
-
330
- <AuthOAuthProviders
331
- providers={['google', 'github', 'discord']}
332
- onClick={handleOAuth}
333
- loading={oauthLoading}
334
- />
335
-
336
- <AuthLink text="Don't have an account?" linkText="Sign up" href="/sign-up" />
337
- </AuthContainer>
338
- );
339
- }
340
- ```
341
-
342
- ### Content Protection
343
-
344
- Protect specific content or sections:
345
-
346
- ```tsx
347
- import { Protect } from '@insforge/react';
348
-
349
- function Dashboard() {
350
- return (
351
- <div>
352
- <h1>Dashboard</h1>
353
-
354
- {/* Simple protection - shows nothing if not signed in */}
355
- <Protect>
356
- <UserContent />
357
- </Protect>
358
-
359
- {/* With redirect */}
360
- <Protect redirectTo="/sign-in">
361
- <UserContent />
362
- </Protect>
363
-
364
- {/* Custom condition - e.g., role-based */}
365
- <Protect condition={(user) => user.email.endsWith('@admin.com')} redirectTo="/unauthorized">
366
- <AdminPanel />
367
- </Protect>
368
- </div>
369
- );
370
- }
371
- ```
372
-
373
- > **Note:** `<Protect>` is for component-level conditional rendering. For app-level route protection, use `<RouteGuard>`
374
-
375
- ---
376
-
377
- ## Route Protection (Detailed)
378
-
379
- ### RouteGuard for Vanilla React
380
-
381
- `RouteGuard` provides app-level authentication protection without requiring any routing library.
382
-
383
- #### Option 1: External Built-in Auth (Simplest)
384
-
385
- Redirects to your deployed Insforge Auth pages:
386
-
387
- ```tsx
388
- import { InsforgeProvider, RouteGuard } from '@insforge/react';
389
-
390
- createRoot(document.getElementById('root')!).render(
391
- <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL} afterSignInUrl="/dashboard">
392
- <RouteGuard
393
- builtInAuth
394
- publicRoutes={['/', '/about', '/pricing']}
395
- loadingFallback={<div>Loading...</div>}
396
- >
397
- <App />
398
- </RouteGuard>
399
- </InsforgeProvider>
400
- );
401
- ```
402
-
403
- **Behavior:**
404
-
405
- - User visits `/sign-in` → Redirects to `baseUrl/auth/sign-in`
406
- - User visits `/sign-up` → Redirects to `baseUrl/auth/sign-up`
407
- - User visits `/dashboard` (protected) → Redirects to `baseUrl/auth/sign-in`
408
- - User visits `/` (public) → ✅ Renders normally
409
-
410
- #### Option 2: Custom Auth Pages
411
-
412
- Use @insforge/react components in your own app:
413
-
414
- ```tsx
415
- import { InsforgeProvider, RouteGuard, SignIn, SignUp } from '@insforge/react';
416
-
417
- // Simple hash-based routing
418
- function App() {
419
- const path = window.location.hash.slice(1) || '/';
420
-
421
- return (
422
- <>
423
- {path === '/login' && <SignIn />}
424
- {path === '/register' && <SignUp />}
425
- {path === '/dashboard' && <Dashboard />}
426
- {path === '/' && <HomePage />}
427
- </>
428
- );
429
- }
430
-
431
- createRoot(document.getElementById('root')!).render(
432
- <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
433
- <RouteGuard
434
- builtInAuth={false}
435
- publicRoutes={['/login', '/register', '/forgot-password', '/']}
436
- paths={{ signIn: '/login', signUp: '/register' }}
437
- loadingFallback={<div>Loading...</div>}
438
- >
439
- <App />
440
- </RouteGuard>
441
- </InsforgeProvider>
442
- );
443
- ```
444
-
445
- **Behavior:**
446
-
447
- - User visits `/login` → ✅ Renders `<SignIn />` (in publicRoutes)
448
- - User visits `/dashboard` (protected) → Redirects to `/login?redirect=/dashboard`
449
- - After login → Redirects to `/dashboard`
450
-
451
- #### RouteGuard Props Reference
452
-
453
- | Prop | Type | Required | Default | Description |
454
- | ---------------------- | ----------- | -------- | ----------------------------- | ---------------------------------------------------------- |
455
- | `builtInAuth` | `boolean` | No | `true` | Use external auth pages (`true`) or custom pages (`false`) |
456
- | `publicRoutes` | `string[]` | No | `[]` | Routes accessible without authentication |
457
- | `paths` | `object` | No | `{ signIn: '/sign-in', ... }` | Custom auth page paths (when `builtInAuth=false`) |
458
- | `paths.signIn` | `string` | No | `'/sign-in'` | Custom sign-in page path |
459
- | `paths.signUp` | `string` | No | `'/sign-up'` | Custom sign-up page path |
460
- | `paths.forgotPassword` | `string` | No | `'/forgot-password'` | Custom forgot password page path |
461
- | `loadingFallback` | `ReactNode` | **Yes** | - | Loading UI displayed while checking authentication |
462
-
463
- **Public Routes with Wildcards:**
464
-
465
- ```tsx
466
- <RouteGuard
467
- publicRoutes={[
468
- '/', // Home page
469
- '/about', // About page
470
- '/blog/*', // All blog routes
471
- '/docs/*', // All documentation routes
472
- ]}
473
- >
474
- <App />
475
- </RouteGuard>
476
- ```
477
-
478
- > **Note:** When `builtInAuth=true`, auth paths (`/sign-in`, `/sign-up`, `/forgot-password`) are automatically redirected. Don't include them in `publicRoutes`.
479
-
480
- ### React Router Integration
481
-
482
- For React Router apps, use the dedicated adapter:
483
-
484
- ```bash
485
- npm install @insforge/react-router
486
- ```
487
-
488
- ```tsx
489
- import { InsforgeProvider } from '@insforge/react-router';
490
- import { getInsforgeRoutes } from '@insforge/react-router/router';
491
- import { createBrowserRouter, RouterProvider } from 'react-router-dom';
492
-
493
- const router = createBrowserRouter([
494
- { path: '/', element: <Home /> },
495
- { path: '/dashboard', element: <Dashboard /> },
496
- ...getInsforgeRoutes({
497
- baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
498
- builtInAuth: true,
499
- }),
500
- ]);
501
-
502
- function App() {
503
- return (
504
- <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
505
- <RouterProvider router={router} />
506
- </InsforgeProvider>
507
- );
508
- }
509
- ```
510
-
511
- **Features:**
512
-
513
- - Pre-configured routes for authentication flows
514
- - React Router's `Link` and `useSearchParams` integration
515
- - Optimized navigation with client-side routing
516
-
517
- **Docs:** [@insforge/react-router](https://github.com/InsForge/InsForge/tree/main/packages/react-router)
518
-
519
- ### Next.js Integration
520
-
521
- For Next.js App Router with SSR:
522
-
523
- ```bash
524
- npm install @insforge/nextjs
525
- ```
526
-
527
- ```tsx
528
- // app/layout.tsx
529
- import { InsforgeProvider } from '@insforge/nextjs';
530
-
531
- export default function RootLayout({ children }) {
532
- return (
533
- <html>
534
- <body>
535
- <InsforgeProvider baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL}>
536
- {children}
537
- </InsforgeProvider>
538
- </body>
539
- </html>
540
- );
541
- }
542
- ```
543
-
544
- **Features:**
545
-
546
- - Server-side rendering (SSR) support
547
- - Middleware-based route protection
548
- - Next.js `Link` and `useSearchParams` integration
549
- - Cookie-based session management
550
- - Automatic token refresh
551
-
552
- **Docs:** [@insforge/nextjs](https://github.com/InsForge/InsForge/tree/main/packages/nextjs)
553
-
554
- ---
555
-
556
- ## OAuth Providers
557
-
558
- Built-in support for 10+ OAuth providers:
559
-
560
- - Google
561
- - GitHub
562
- - Discord
563
- - Apple
564
- - Microsoft
565
- - Facebook
566
- - LinkedIn
567
- - Instagram
568
- - TikTok
569
- - Spotify
570
- - X (Twitter)
571
-
572
- Providers are auto-detected from your backend configuration.
573
-
574
- ---
575
-
576
- ## Available Atomic Components
577
-
578
- Low-level building blocks for complete customization:
579
-
580
- - `<AuthBranding />` - Insforge branding footer
581
- - `<AuthContainer />` - Main container wrapper
582
- - `<AuthHeader />` - Title and subtitle display
583
- - `<AuthErrorBanner />` - Error message display
584
- - `<AuthFormField />` - Standard input field
585
- - `<AuthPasswordField />` - Password input with features
586
- - `<AuthPasswordStrengthIndicator />` - Password checklist
587
- - `<AuthSubmitButton />` - Submit button with states
588
- - `<AuthLink />` - Call-to-action link
589
- - `<AuthDivider />` - Visual separator
590
- - `<AuthOAuthButton />` - Single OAuth provider button
591
- - `<AuthOAuthProviders />` - Smart OAuth grid
592
- - `<AuthVerificationCodeInput />` - 6-digit OTP input
593
- - `<AuthEmailVerificationStep />` - Email verification step with countdown and resend
594
-
595
- ---
596
-
597
- ## API Reference
598
-
599
- ### InsforgeProvider
600
-
601
- The root provider component that manages authentication state.
602
-
603
- **Props:**
604
-
605
- | Prop | Type | Required | Default | Description |
606
- | ---------------- | -------------------------------------- | -------- | ------- | --------------------------------------------------- |
607
- | `baseUrl` | `string` | **Yes** | - | Your Insforge backend URL |
608
- | `afterSignInUrl` | `string` | No | `'/'` | Redirect URL after successful sign-in |
609
- | `onAuthChange` | `(user: InsforgeUser \| null) => void` | No | - | Callback when auth state changes |
610
- | `onSignIn` | `(authToken: string) => Promise<void>` | No | - | Custom handler after sign-in (e.g., cookie sync) |
611
- | `onSignOut` | `() => Promise<void>` | No | - | Custom handler after sign-out (e.g., clear cookies) |
612
-
613
- **Example:**
614
-
615
- ```tsx
616
- <InsforgeProvider
617
- baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}
618
- afterSignInUrl="/dashboard"
619
- onAuthChange={(user) => {
620
- console.log('Auth changed:', user);
621
- }}
622
- >
623
- {children}
624
- </InsforgeProvider>
625
- ```
626
-
627
- ### RouteGuard
628
-
629
- App-level route protection for vanilla React apps (no router library needed).
630
-
631
- See [Route Protection (Detailed)](#route-protection-detailed) for full documentation.
632
-
633
- **Quick Props:**
634
-
635
- - `builtInAuth` (default: `true`) - Use external auth or custom pages
636
- - `publicRoutes` - Array of paths accessible without auth
637
- - `paths` - Custom auth page paths (when `builtInAuth=false`)
638
- - `loadingFallback` (required) - Loading UI
639
-
640
- ### useAuth() / useInsforge()
641
-
642
- Primary hook for authentication. Both are aliases for the same hook.
643
-
644
- **Returns:**
645
-
646
- ```tsx
647
- {
648
- // Auth state
649
- user: InsforgeUser | null;
650
- isLoaded: boolean;
651
- isSignedIn: boolean;
652
-
653
- // Auth methods
654
- signIn: (email: string, password: string) => Promise<...>;
655
- signUp: (email: string, password: string) => Promise<...>;
656
- signOut: () => Promise<void>;
657
- updateUser: (data: Partial<InsforgeUser>) => Promise<...>;
658
- reloadAuth: () => Promise<...>;
659
-
660
- // Email verification
661
- resendVerificationEmail: (email: string) => Promise<...>;
662
- verifyEmail: (otp: string, email?: string) => Promise<...>;
663
-
664
- // Password reset
665
- sendResetPasswordEmail: (email: string) => Promise<...>;
666
- resetPassword: (token: string, newPassword: string) => Promise<...>;
667
- exchangeResetPasswordToken: (email: string, code: string) => Promise<...>;
668
-
669
- // OAuth
670
- loginWithOAuth: (provider: OAuthProvider, redirectTo: string) => Promise<void>;
671
-
672
- // Config (from provider)
673
- baseUrl: string;
674
- afterSignInUrl: string;
675
-
676
- // Public config
677
- getPublicAuthConfig: () => Promise<...>;
678
- }
679
- ```
680
-
681
- ### useUser()
682
-
683
- Simplified hook for user data only.
684
-
685
- **Returns:**
686
-
687
- ```tsx
688
- {
689
- user: InsforgeUser | null;
690
- isLoaded: boolean;
691
- }
692
- ```
693
-
694
- ### usePublicAuthConfig()
695
-
696
- Hook for fetching public auth configuration (OAuth providers, password requirements, etc.).
697
-
698
- **Returns:**
699
-
700
- ```tsx
701
- {
702
- oauthProviders: OAuthProviderConfig[];
703
- authConfig: AuthConfig;
704
- isLoaded: boolean;
705
- }
706
- ```
707
-
708
- ---
709
-
710
- ## Support
711
-
712
- - **Documentation**: https://docs.insforge.dev
713
- - **GitHub Issues**: https://github.com/InsForge/InsForge/issues
714
- - **Discord Community**: https://discord.com/invite/DvBtaEc9Jz
715
-
716
- ## License
717
-
718
- MIT © Insforge
1
+ # @insforge/react
2
+
3
+ **Framework-agnostic authentication solution for React applications.** Production-ready components with full business logic included.
4
+
5
+ > **✨ CSS-in-JS**: All components now use Emotion CSS-in-JS for zero FOUC in SSR environments. No CSS imports needed!
6
+
7
+ ## Why @insforge/react?
8
+
9
+ ✅ **Framework Agnostic** - Works with any React setup (Vite, CRA, or no bundler)
10
+ ✅ **Zero Router Dependencies** - Built-in navigation abstraction works with any routing solution
11
+ ✅ **Route Protection** - Built-in `RouteGuard` for vanilla React apps
12
+ ✅ **Production Ready** - Complete auth flows with business logic included
13
+ ✅ **Full TypeScript** - Complete type safety out of the box
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ Get authentication working in your React app in 5 minutes.
20
+
21
+ ### 1. Install
22
+
23
+ ```bash
24
+ npm install @insforge/react
25
+ # or
26
+ yarn add @insforge/react
27
+ # or
28
+ pnpm add @insforge/react
29
+ ```
30
+
31
+ #### Environment Variables
32
+
33
+ ```bash
34
+ # .env
35
+ VITE_INSFORGE_BASE_URL=https://your-project.insforge.app/
36
+ ```
37
+
38
+ ### 2. Setup Provider & Route Guard
39
+
40
+ Wrap your app with `InsforgeProvider`:
41
+
42
+ ```tsx
43
+ // src/main.tsx (Vite) or src/index.tsx (CRA)
44
+ import { StrictMode } from 'react';
45
+ import { createRoot } from 'react-dom/client';
46
+ import { InsforgeProvider } from '@insforge/react';
47
+ import App from './App';
48
+
49
+ createRoot(document.getElementById('root')!).render(
50
+ <StrictMode>
51
+ <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
52
+ <App />
53
+ </InsforgeProvider>
54
+ </StrictMode>
55
+ );
56
+ ```
57
+
58
+ ### 3. Use Components & Hooks
59
+
60
+ Now you can use authentication components and hooks anywhere in your app:
61
+
62
+ ```tsx
63
+ // src/App.tsx
64
+ import { SignInButton, SignUpButton, SignedIn, SignedOut, UserButton } from '@insforge/react';
65
+
66
+ export default function App() {
67
+ return (
68
+ <div>
69
+ <SignedOut>
70
+ <SignInButton />
71
+ <SignUpButton />
72
+ </SignedOut>
73
+
74
+ <SignedIn>
75
+ <nav>
76
+ <UserButton />
77
+ </nav>
78
+ <h1>Welcome to your dashboard!</h1>
79
+ </SignedIn>
80
+ </div>
81
+ );
82
+ }
83
+ ```
84
+
85
+ **That's it!** 🎉 Your app is now protected with authentication.
86
+
87
+ ---
88
+
89
+ ## Usage Patterns
90
+
91
+ ### Option 1: Pre-built Components (Fastest)
92
+
93
+ Use complete auth flows with built-in UI and logic:
94
+
95
+ ```tsx
96
+ import { SignIn, SignUp, ForgotPassword, ResetPassword } from '@insforge/react';
97
+
98
+ // In your app
99
+ <SignIn /> // Complete sign-in flow
100
+ <SignUp /> // Complete sign-up flow with email verification
101
+ <ForgotPassword /> // Password reset request + verification
102
+ <ResetPassword /> // Reset password with token (from URL params)
103
+ ```
104
+
105
+ ### Option 2: Form Components (UI Only)
106
+
107
+ Use UI components and add your own logic:
108
+
109
+ ```tsx
110
+ import { SignInForm, useAuth } from '@insforge/react';
111
+ import { useState } from 'react';
112
+
113
+ function CustomSignIn() {
114
+ const { signIn } = useAuth();
115
+ const [email, setEmail] = useState('');
116
+ const [password, setPassword] = useState('');
117
+ const [error, setError] = useState('');
118
+ const [loading, setLoading] = useState(false);
119
+
120
+ const handleSubmit = async (e) => {
121
+ e.preventDefault();
122
+ setLoading(true);
123
+ const result = await signIn(email, password);
124
+ if ('error' in result) {
125
+ setError(result.error);
126
+ }
127
+ setLoading(false);
128
+ };
129
+
130
+ return (
131
+ <SignInForm
132
+ email={email}
133
+ password={password}
134
+ onEmailChange={setEmail}
135
+ onPasswordChange={setPassword}
136
+ onSubmit={handleSubmit}
137
+ error={error}
138
+ loading={loading}
139
+ />
140
+ );
141
+ }
142
+ ```
143
+
144
+ ### Option 3: Hooks Only (Headless)
145
+
146
+ Build completely custom UI using authentication hooks:
147
+
148
+ ```tsx
149
+ import { useAuth } from '@insforge/react';
150
+
151
+ function CustomAuthForm() {
152
+ const { signIn, signUp, isLoaded } = useAuth();
153
+
154
+ const handleLogin = async (email: string, password: string) => {
155
+ const result = await signIn(email, password);
156
+ if ('error' in result) {
157
+ console.error(result.error);
158
+ } else {
159
+ console.log('Signed in!');
160
+ }
161
+ };
162
+
163
+ return <form>...your custom UI...</form>;
164
+ }
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Core Features
170
+
171
+ ### Components
172
+
173
+ **Pre-built with Business Logic:**
174
+
175
+ - `<SignIn />` - Complete sign-in with email/password & OAuth
176
+ - `<SignUp />` - Registration with password validation & email verification
177
+ - `<ForgotPassword />` - Request password reset with email validation
178
+ - `<ResetPassword />` - Reset password with token validation
179
+ - `<VerifyEmail />` - Verify email with automatic token handling
180
+ - `<UserButton />` - User dropdown with sign-out
181
+ - `<RouteGuard />` - **NEW:** App-level route protection for vanilla React
182
+ - `<Protect />` - Component-level protection wrapper
183
+ - `<SignedIn>` / `<SignedOut>` - Conditional rendering
184
+
185
+ **Form Components (Pure UI):**
186
+
187
+ - `<SignInForm />` - Sign-in UI without logic
188
+ - `<SignUpForm />` - Sign-up UI without logic
189
+ - `<ForgotPasswordForm />` - Password reset request UI
190
+ - `<ResetPasswordForm />` - Password reset with token UI
191
+ - `<VerifyEmailStatus />` - Email verification status UI
192
+
193
+ **Atomic Components (14 total):**
194
+
195
+ - `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, `<AuthEmailVerificationStep />`, etc.
196
+
197
+ ### Hooks
198
+
199
+ ```tsx
200
+ // Authentication state and methods
201
+ const {
202
+ signIn,
203
+ signUp,
204
+ signOut,
205
+ isSignedIn,
206
+ isLoaded,
207
+ baseUrl, // From provider
208
+ afterSignInUrl, // From provider
209
+ } = useAuth();
210
+
211
+ // Or use useInsforge (same as useAuth)
212
+ const context = useInsforge();
213
+
214
+ // User information
215
+ const { user, updateUser, isLoaded } = useUser();
216
+
217
+ // Public auth configuration (OAuth providers, password requirements, etc.)
218
+ const { oauthProviders, authConfig, isLoaded } = usePublicAuthConfig();
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Customization
224
+
225
+ ### Text Customization
226
+
227
+ All components support full text customization:
228
+
229
+ ```tsx
230
+ <SignIn
231
+ title="Welcome Back!"
232
+ subtitle="We're happy to see you again"
233
+ emailLabel="Your Email Address"
234
+ emailPlaceholder="you@company.com"
235
+ passwordLabel="Your Password"
236
+ submitButtonText="Login Now"
237
+ loadingButtonText="Signing you in..."
238
+ signUpText="New to our platform?"
239
+ signUpLinkText="Create an account"
240
+ dividerText="or continue with"
241
+ />
242
+
243
+ <ForgotPassword
244
+ title="Reset Your Password"
245
+ subtitle="Enter your email to receive a reset code"
246
+ emailLabel="Email Address"
247
+ submitButtonText="Send Reset Code"
248
+ backToSignInText="Remember your password?"
249
+ successTitle="Check Your Email"
250
+ successMessage="We've sent a reset code to your inbox"
251
+ />
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Advanced Usage
257
+
258
+ ### Conditional Rendering
259
+
260
+ Control what users see based on auth state:
261
+
262
+ ```tsx
263
+ import { SignedIn, SignedOut, Protect } from '@insforge/react';
264
+
265
+ function App() {
266
+ return (
267
+ <>
268
+ <SignedOut>
269
+ <SignIn />
270
+ </SignedOut>
271
+
272
+ <SignedIn>
273
+ <Dashboard />
274
+ </SignedIn>
275
+
276
+ {/* Or use Protect for specific sections */}
277
+ <Protect redirectTo="/sign-in">
278
+ <ProtectedContent />
279
+ </Protect>
280
+ </>
281
+ );
282
+ }
283
+ ```
284
+
285
+ ### Build from Atomic Components
286
+
287
+ ```tsx
288
+ import {
289
+ AuthContainer,
290
+ AuthHeader,
291
+ AuthFormField,
292
+ AuthPasswordField,
293
+ AuthSubmitButton,
294
+ AuthErrorBanner,
295
+ AuthDivider,
296
+ AuthOAuthProviders,
297
+ AuthLink,
298
+ } from '@insforge/react';
299
+
300
+ function CompletelyCustomAuth() {
301
+ return (
302
+ <AuthContainer>
303
+ <AuthHeader title="Welcome to MyApp" subtitle="Sign in to continue" />
304
+
305
+ <AuthErrorBanner error={error} />
306
+
307
+ <form onSubmit={handleSubmit}>
308
+ <AuthFormField
309
+ id="email"
310
+ type="email"
311
+ label="Email"
312
+ value={email}
313
+ onChange={(e) => setEmail(e.target.value)}
314
+ />
315
+
316
+ <AuthPasswordField
317
+ id="password"
318
+ label="Password"
319
+ value={password}
320
+ onChange={(e) => setPassword(e.target.value)}
321
+ authConfig={config}
322
+ showStrengthIndicator
323
+ />
324
+
325
+ <AuthSubmitButton isLoading={loading}>Sign In</AuthSubmitButton>
326
+ </form>
327
+
328
+ <AuthDivider text="or" />
329
+
330
+ <AuthOAuthProviders
331
+ providers={['google', 'github', 'discord']}
332
+ onClick={handleOAuth}
333
+ loading={oauthLoading}
334
+ />
335
+
336
+ <AuthLink text="Don't have an account?" linkText="Sign up" href="/sign-up" />
337
+ </AuthContainer>
338
+ );
339
+ }
340
+ ```
341
+
342
+ ### Content Protection
343
+
344
+ Protect specific content or sections:
345
+
346
+ ```tsx
347
+ import { Protect } from '@insforge/react';
348
+
349
+ function Dashboard() {
350
+ return (
351
+ <div>
352
+ <h1>Dashboard</h1>
353
+
354
+ {/* Simple protection - shows nothing if not signed in */}
355
+ <Protect>
356
+ <UserContent />
357
+ </Protect>
358
+
359
+ {/* With redirect */}
360
+ <Protect redirectTo="/sign-in">
361
+ <UserContent />
362
+ </Protect>
363
+
364
+ {/* Custom condition - e.g., role-based */}
365
+ <Protect condition={(user) => user.email.endsWith('@admin.com')} redirectTo="/unauthorized">
366
+ <AdminPanel />
367
+ </Protect>
368
+ </div>
369
+ );
370
+ }
371
+ ```
372
+
373
+ > **Note:** `<Protect>` is for component-level conditional rendering. For app-level route protection, use `<RouteGuard>`
374
+
375
+ ---
376
+
377
+ ## Route Protection (Detailed)
378
+
379
+ ### RouteGuard for Vanilla React
380
+
381
+ `RouteGuard` provides app-level authentication protection without requiring any routing library.
382
+
383
+ #### Option 1: External Built-in Auth (Simplest)
384
+
385
+ Redirects to your deployed Insforge Auth pages:
386
+
387
+ ```tsx
388
+ import { InsforgeProvider, RouteGuard } from '@insforge/react';
389
+
390
+ createRoot(document.getElementById('root')!).render(
391
+ <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL} afterSignInUrl="/dashboard">
392
+ <RouteGuard
393
+ builtInAuth
394
+ publicRoutes={['/', '/about', '/pricing']}
395
+ loadingFallback={<div>Loading...</div>}
396
+ >
397
+ <App />
398
+ </RouteGuard>
399
+ </InsforgeProvider>
400
+ );
401
+ ```
402
+
403
+ **Behavior:**
404
+
405
+ - User visits `/sign-in` → Redirects to `baseUrl/auth/sign-in`
406
+ - User visits `/sign-up` → Redirects to `baseUrl/auth/sign-up`
407
+ - User visits `/dashboard` (protected) → Redirects to `baseUrl/auth/sign-in`
408
+ - User visits `/` (public) → ✅ Renders normally
409
+
410
+ #### Option 2: Custom Auth Pages
411
+
412
+ Use @insforge/react components in your own app:
413
+
414
+ ```tsx
415
+ import { InsforgeProvider, RouteGuard, SignIn, SignUp } from '@insforge/react';
416
+
417
+ // Simple hash-based routing
418
+ function App() {
419
+ const path = window.location.hash.slice(1) || '/';
420
+
421
+ return (
422
+ <>
423
+ {path === '/login' && <SignIn />}
424
+ {path === '/register' && <SignUp />}
425
+ {path === '/dashboard' && <Dashboard />}
426
+ {path === '/' && <HomePage />}
427
+ </>
428
+ );
429
+ }
430
+
431
+ createRoot(document.getElementById('root')!).render(
432
+ <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
433
+ <RouteGuard
434
+ builtInAuth={false}
435
+ publicRoutes={['/login', '/register', '/forgot-password', '/']}
436
+ paths={{ signIn: '/login', signUp: '/register' }}
437
+ loadingFallback={<div>Loading...</div>}
438
+ >
439
+ <App />
440
+ </RouteGuard>
441
+ </InsforgeProvider>
442
+ );
443
+ ```
444
+
445
+ **Behavior:**
446
+
447
+ - User visits `/login` → ✅ Renders `<SignIn />` (in publicRoutes)
448
+ - User visits `/dashboard` (protected) → Redirects to `/login?redirect=/dashboard`
449
+ - After login → Redirects to `/dashboard`
450
+
451
+ #### RouteGuard Props Reference
452
+
453
+ | Prop | Type | Required | Default | Description |
454
+ | ---------------------- | ----------- | -------- | ----------------------------- | ---------------------------------------------------------- |
455
+ | `builtInAuth` | `boolean` | No | `true` | Use external auth pages (`true`) or custom pages (`false`) |
456
+ | `publicRoutes` | `string[]` | No | `[]` | Routes accessible without authentication |
457
+ | `paths` | `object` | No | `{ signIn: '/sign-in', ... }` | Custom auth page paths (when `builtInAuth=false`) |
458
+ | `paths.signIn` | `string` | No | `'/sign-in'` | Custom sign-in page path |
459
+ | `paths.signUp` | `string` | No | `'/sign-up'` | Custom sign-up page path |
460
+ | `paths.forgotPassword` | `string` | No | `'/forgot-password'` | Custom forgot password page path |
461
+ | `loadingFallback` | `ReactNode` | **Yes** | - | Loading UI displayed while checking authentication |
462
+
463
+ **Public Routes with Wildcards:**
464
+
465
+ ```tsx
466
+ <RouteGuard
467
+ publicRoutes={[
468
+ '/', // Home page
469
+ '/about', // About page
470
+ '/blog/*', // All blog routes
471
+ '/docs/*', // All documentation routes
472
+ ]}
473
+ >
474
+ <App />
475
+ </RouteGuard>
476
+ ```
477
+
478
+ > **Note:** When `builtInAuth=true`, auth paths (`/sign-in`, `/sign-up`, `/forgot-password`) are automatically redirected. Don't include them in `publicRoutes`.
479
+
480
+ ### React Router Integration
481
+
482
+ For React Router apps, use the dedicated adapter:
483
+
484
+ ```bash
485
+ npm install @insforge/react-router
486
+ ```
487
+
488
+ ```tsx
489
+ import { InsforgeProvider } from '@insforge/react-router';
490
+ import { getInsforgeRoutes } from '@insforge/react-router/router';
491
+ import { createBrowserRouter, RouterProvider } from 'react-router-dom';
492
+
493
+ const router = createBrowserRouter([
494
+ { path: '/', element: <Home /> },
495
+ { path: '/dashboard', element: <Dashboard /> },
496
+ ...getInsforgeRoutes({
497
+ baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
498
+ builtInAuth: true,
499
+ }),
500
+ ]);
501
+
502
+ function App() {
503
+ return (
504
+ <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
505
+ <RouterProvider router={router} />
506
+ </InsforgeProvider>
507
+ );
508
+ }
509
+ ```
510
+
511
+ **Features:**
512
+
513
+ - Pre-configured routes for authentication flows
514
+ - React Router's `Link` and `useSearchParams` integration
515
+ - Optimized navigation with client-side routing
516
+
517
+ **Docs:** [@insforge/react-router](https://github.com/InsForge/InsForge/tree/main/packages/react-router)
518
+
519
+ ### Next.js Integration
520
+
521
+ For Next.js App Router with SSR:
522
+
523
+ ```bash
524
+ npm install @insforge/nextjs
525
+ ```
526
+
527
+ ```tsx
528
+ // app/layout.tsx
529
+ import { InsforgeProvider } from '@insforge/nextjs';
530
+
531
+ export default function RootLayout({ children }) {
532
+ return (
533
+ <html>
534
+ <body>
535
+ <InsforgeProvider baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL}>
536
+ {children}
537
+ </InsforgeProvider>
538
+ </body>
539
+ </html>
540
+ );
541
+ }
542
+ ```
543
+
544
+ **Features:**
545
+
546
+ - Server-side rendering (SSR) support
547
+ - Middleware-based route protection
548
+ - Next.js `Link` and `useSearchParams` integration
549
+ - Cookie-based session management
550
+ - Automatic token refresh
551
+
552
+ **Docs:** [@insforge/nextjs](https://github.com/InsForge/InsForge/tree/main/packages/nextjs)
553
+
554
+ ---
555
+
556
+ ## OAuth Providers
557
+
558
+ Built-in support for 10+ OAuth providers:
559
+
560
+ - Google
561
+ - GitHub
562
+ - Discord
563
+ - Apple
564
+ - Microsoft
565
+ - Facebook
566
+ - LinkedIn
567
+ - Instagram
568
+ - TikTok
569
+ - Spotify
570
+ - X (Twitter)
571
+
572
+ Providers are auto-detected from your backend configuration.
573
+
574
+ ---
575
+
576
+ ## Available Atomic Components
577
+
578
+ Low-level building blocks for complete customization:
579
+
580
+ - `<AuthBranding />` - Insforge branding footer
581
+ - `<AuthContainer />` - Main container wrapper
582
+ - `<AuthHeader />` - Title and subtitle display
583
+ - `<AuthErrorBanner />` - Error message display
584
+ - `<AuthFormField />` - Standard input field
585
+ - `<AuthPasswordField />` - Password input with features
586
+ - `<AuthPasswordStrengthIndicator />` - Password checklist
587
+ - `<AuthSubmitButton />` - Submit button with states
588
+ - `<AuthLink />` - Call-to-action link
589
+ - `<AuthDivider />` - Visual separator
590
+ - `<AuthOAuthButton />` - Single OAuth provider button
591
+ - `<AuthOAuthProviders />` - Smart OAuth grid
592
+ - `<AuthVerificationCodeInput />` - 6-digit OTP input
593
+ - `<AuthEmailVerificationStep />` - Email verification step with countdown and resend
594
+
595
+ ---
596
+
597
+ ## API Reference
598
+
599
+ ### InsforgeProvider
600
+
601
+ The root provider component that manages authentication state.
602
+
603
+ **Props:**
604
+
605
+ | Prop | Type | Required | Default | Description |
606
+ | ---------------- | -------------------------------------- | -------- | ------- | --------------------------------------------------- |
607
+ | `baseUrl` | `string` | **Yes** | - | Your Insforge backend URL |
608
+ | `afterSignInUrl` | `string` | No | `'/'` | Redirect URL after successful sign-in |
609
+ | `onAuthChange` | `(user: InsforgeUser \| null) => void` | No | - | Callback when auth state changes |
610
+ | `onSignIn` | `(authToken: string) => Promise<void>` | No | - | Custom handler after sign-in (e.g., cookie sync) |
611
+ | `onSignOut` | `() => Promise<void>` | No | - | Custom handler after sign-out (e.g., clear cookies) |
612
+
613
+ **Example:**
614
+
615
+ ```tsx
616
+ <InsforgeProvider
617
+ baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}
618
+ afterSignInUrl="/dashboard"
619
+ onAuthChange={(user) => {
620
+ console.log('Auth changed:', user);
621
+ }}
622
+ >
623
+ {children}
624
+ </InsforgeProvider>
625
+ ```
626
+
627
+ ### RouteGuard
628
+
629
+ App-level route protection for vanilla React apps (no router library needed).
630
+
631
+ See [Route Protection (Detailed)](#route-protection-detailed) for full documentation.
632
+
633
+ **Quick Props:**
634
+
635
+ - `builtInAuth` (default: `true`) - Use external auth or custom pages
636
+ - `publicRoutes` - Array of paths accessible without auth
637
+ - `paths` - Custom auth page paths (when `builtInAuth=false`)
638
+ - `loadingFallback` (required) - Loading UI
639
+
640
+ ### useAuth() / useInsforge()
641
+
642
+ Primary hook for authentication. Both are aliases for the same hook.
643
+
644
+ **Returns:**
645
+
646
+ ```tsx
647
+ {
648
+ // Auth state
649
+ user: InsforgeUser | null;
650
+ isLoaded: boolean;
651
+ isSignedIn: boolean;
652
+
653
+ // Auth methods
654
+ signIn: (email: string, password: string) => Promise<...>;
655
+ signUp: (email: string, password: string) => Promise<...>;
656
+ signOut: () => Promise<void>;
657
+ updateUser: (data: Partial<InsforgeUser>) => Promise<...>;
658
+ reloadAuth: () => Promise<...>;
659
+
660
+ // Email verification
661
+ resendVerificationEmail: (email: string) => Promise<...>;
662
+ verifyEmail: (otp: string, email?: string) => Promise<...>;
663
+
664
+ // Password reset
665
+ sendResetPasswordEmail: (email: string) => Promise<...>;
666
+ resetPassword: (token: string, newPassword: string) => Promise<...>;
667
+ exchangeResetPasswordToken: (email: string, code: string) => Promise<...>;
668
+
669
+ // OAuth
670
+ loginWithOAuth: (provider: OAuthProvider, redirectTo: string) => Promise<void>;
671
+
672
+ // Config (from provider)
673
+ baseUrl: string;
674
+ afterSignInUrl: string;
675
+
676
+ // Public config
677
+ getPublicAuthConfig: () => Promise<...>;
678
+ }
679
+ ```
680
+
681
+ ### useUser()
682
+
683
+ Simplified hook for user data only.
684
+
685
+ **Returns:**
686
+
687
+ ```tsx
688
+ {
689
+ user: InsforgeUser | null;
690
+ isLoaded: boolean;
691
+ }
692
+ ```
693
+
694
+ ### usePublicAuthConfig()
695
+
696
+ Hook for fetching public auth configuration (OAuth providers, password requirements, etc.).
697
+
698
+ **Returns:**
699
+
700
+ ```tsx
701
+ {
702
+ oauthProviders: OAuthProviderConfig[];
703
+ authConfig: AuthConfig;
704
+ isLoaded: boolean;
705
+ }
706
+ ```
707
+
708
+ ---
709
+
710
+ ## Support
711
+
712
+ - **Documentation**: https://docs.insforge.dev
713
+ - **GitHub Issues**: https://github.com/InsForge/InsForge/issues
714
+ - **Discord Community**: https://discord.com/invite/DvBtaEc9Jz
715
+
716
+ ## License
717
+
718
+ MIT © Insforge