@insforge/react 0.3.2 → 0.3.3

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,604 +1,604 @@
1
- # @insforge/react
2
-
3
- **Complete authentication solution for React applications.** Production-ready components with full business logic included.
4
-
5
- ## Why @insforge/react?
6
-
7
- ✅ **5-Minute Setup** - One provider + one line of router config = done
8
- ✅ **Built-in Auth UI** - Use deployed auth pages (like Next.js middleware)
9
- ✅ **Framework Agnostic** - Works with any React framework
10
- ✅ **Full TypeScript** - Complete type safety out of the box
11
- ✅ **Fully Customizable** - Deep styling control when you need it
12
-
13
- ---
14
-
15
- ## Quick Start
16
-
17
- Get authentication working in your React app in 5 minutes.
18
-
19
- ### 1. Install
20
-
21
- ```bash
22
- npm install @insforge/react
23
- # or
24
- yarn add @insforge/react
25
- # or
26
- pnpm add @insforge/react
27
- ```
28
-
29
- ### 2. Setup Provider
30
-
31
- Wrap your app with `InsforgeProvider`:
32
-
33
- ```tsx
34
- // src/main.tsx (Vite) or src/index.tsx (CRA)
35
- import { StrictMode } from 'react';
36
- import { createRoot } from 'react-dom/client';
37
- import { InsforgeProvider } from '@insforge/react';
38
- import '@insforge/react/styles.css';
39
- import App from './App';
40
-
41
- createRoot(document.getElementById('root')!).render(
42
- <StrictMode>
43
- <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
44
- <App />
45
- </InsforgeProvider>
46
- </StrictMode>
47
- );
48
- ```
49
-
50
- ### 3. Configure Router (Built-in Auth)
51
-
52
- ```tsx
53
- // src/App.tsx
54
- import { createBrowserRouter, RouterProvider } from 'react-router-dom';
55
- import { getInsforgeRoutes } from '@insforge/react/router';
56
- import Home from './pages/Home';
57
- import Dashboard from './pages/Dashboard';
58
-
59
- const router = createBrowserRouter([
60
- { path: '/', element: <Home /> },
61
-
62
- ...getInsforgeRoutes({
63
- baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
64
- builtInAuth: true
65
- }),
66
-
67
- { path: '/dashboard', element: <Dashboard /> }
68
- ]);
69
-
70
- export default function App() {
71
- return <RouterProvider router={router} />;
72
- }
73
- ```
74
-
75
- **What this does:**
76
- - Visiting `/sign-in` → Redirects to `your-project.insforge.app/auth/sign-in`
77
- - Visiting `/sign-up` → Redirects to `your-project.insforge.app/auth/sign-up`
78
- - After auth → Redirects back to `/auth/callback` → Goes to dashboard
79
-
80
- ### 4. Add Auth UI to Your Pages
81
-
82
- ```tsx
83
- // src/pages/Home.tsx
84
- import { SignedIn, SignedOut, UserButton } from '@insforge/react';
85
-
86
- export default function Home() {
87
- return (
88
- <div>
89
- <nav>
90
- <SignedOut>
91
- <a href="/sign-in">Sign In</a>
92
- </SignedOut>
93
-
94
- <SignedIn>
95
- <UserButton afterSignOutUrl="/" />
96
- </SignedIn>
97
- </nav>
98
-
99
- <h1>Welcome to My App!</h1>
100
- </div>
101
- );
102
- }
103
- ```
104
-
105
- **That's it!** 🎉 You now have production-ready authentication.
106
-
107
- ---
108
-
109
- ## Router Configuration Options
110
-
111
- ### Built-in Auth (Recommended)
112
-
113
- Uses your deployed Insforge auth pages (includes all flows):
114
-
115
- ```tsx
116
- ...getInsforgeRoutes({
117
- baseUrl: 'https://your-project.insforge.app',
118
- builtInAuth: true, // Default
119
- paths: {
120
- signIn: '/sign-in', // Sign in page
121
- signUp: '/sign-up', // Sign up page
122
- verifyEmail: '/verify-email', // Email verification page
123
- forgotPassword: '/forgot-password', // Request password reset
124
- resetPassword: '/reset-password', // Reset password with token
125
- callback: '/auth/callback' // OAuth callback handler
126
- }
127
- })
128
- ```
129
-
130
- ### Custom UI Components
131
-
132
- Use package components with your own styling:
133
-
134
- ```tsx
135
- import {
136
- SignIn,
137
- SignUp,
138
- ForgotPassword,
139
- ResetPassword,
140
- VerifyEmail
141
- } from '@insforge/react';
142
-
143
- const router = createBrowserRouter([
144
- { path: '/', element: <Home /> },
145
-
146
- // Still need callback route for OAuth
147
- ...getInsforgeRoutes({
148
- baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
149
- builtInAuth: false // Don't redirect to deployed UI
150
- }),
151
-
152
- // Use package components for complete auth flows
153
- { path: '/sign-in', element: <SignIn afterSignInUrl="/dashboard" /> },
154
- { path: '/sign-up', element: <SignUp afterSignUpUrl="/dashboard" /> },
155
- { path: '/forgot-password', element: <ForgotPassword backToSignInUrl="/sign-in" /> },
156
- { path: '/reset-password', element: <ResetPassword token={searchParams.get('token')} /> },
157
- { path: '/verify-email', element: <VerifyEmail token={searchParams.get('token')} /> }
158
- ]);
159
- ```
160
-
161
- ### Fully Custom UI
162
-
163
- Build your own auth pages from scratch:
164
-
165
- ```tsx
166
- import { useAuth } from '@insforge/react';
167
-
168
- function CustomSignIn() {
169
- const { signIn } = useAuth();
170
-
171
- const handleSubmit = async (e) => {
172
- e.preventDefault();
173
- await signIn(email, password);
174
- navigate('/dashboard');
175
- };
176
-
177
- return <form onSubmit={handleSubmit}>...</form>;
178
- }
179
- ```
180
-
181
- ---
182
-
183
- ## Core Features
184
-
185
- ### Components
186
-
187
- **Pre-built with Business Logic:**
188
- - `<SignIn />` - Complete sign-in with email/password & OAuth
189
- - `<SignUp />` - Registration with password validation & email verification
190
- - `<ForgotPassword />` - Request password reset with email validation
191
- - `<ResetPassword />` - Reset password with token validation
192
- - `<VerifyEmail />` - Verify email with automatic token handling
193
- - `<UserButton />` - User dropdown with sign-out
194
- - `<Protect />` - Route protection wrapper
195
- - `<SignedIn>` / `<SignedOut>` - Conditional rendering
196
- - `<InsforgeCallback />` - OAuth callback handler
197
-
198
- **Form Components (Pure UI):**
199
- - `<SignInForm />` - Sign-in UI without logic
200
- - `<SignUpForm />` - Sign-up UI without logic
201
- - `<ForgotPasswordForm />` - Password reset request UI
202
- - `<ResetPasswordForm />` - Password reset with token UI
203
- - `<VerifyEmailStatus />` - Email verification status UI
204
-
205
- **Atomic Components (14 total):**
206
- - `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, `<AuthEmailVerificationStep />`, etc.
207
-
208
- ### Hooks
209
-
210
- ```tsx
211
- const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
212
- const { user, updateUser, isLoaded } = useUser();
213
- const { oauthProviders, emailConfig, isLoaded } = usePublicAuthConfig();
214
- ```
215
-
216
- ---
217
-
218
- ## Customization
219
-
220
- ### Basic Styling
221
-
222
- All components support `appearance` props:
223
-
224
- ```tsx
225
- <SignIn
226
- appearance={{
227
- container: "max-w-lg",
228
- card: "bg-white shadow-2xl",
229
- button: "bg-blue-600 hover:bg-blue-700"
230
- }}
231
- />
232
-
233
- // Works with all auth components
234
- <ForgotPassword
235
- appearance={{
236
- card: "bg-gradient-to-br from-indigo-50 to-white",
237
- button: "bg-indigo-600 hover:bg-indigo-700"
238
- }}
239
- />
240
- ```
241
-
242
- ### Deep Customization (Hierarchical Appearance)
243
-
244
- Style nested components through hierarchical structure:
245
-
246
- ```tsx
247
- <SignIn
248
- appearance={{
249
- card: "bg-gradient-to-br from-blue-50 to-white shadow-2xl",
250
- header: {
251
- title: "text-3xl font-bold text-purple-900",
252
- subtitle: "text-purple-600"
253
- },
254
- form: {
255
- emailField: {
256
- label: "text-gray-800 font-semibold",
257
- input: "border-purple-300 focus:border-purple-500 rounded-lg"
258
- },
259
- passwordField: {
260
- input: "border-purple-300 focus:border-purple-500 rounded-lg",
261
- forgotPasswordLink: "text-purple-600 hover:text-purple-800"
262
- }
263
- },
264
- button: "bg-purple-600 hover:bg-purple-700 rounded-lg h-12",
265
- link: {
266
- text: "text-gray-600",
267
- link: "text-purple-600 hover:text-purple-800 font-semibold"
268
- },
269
- oauth: {
270
- button: "border-2 hover:bg-gray-50 rounded-xl"
271
- }
272
- }}
273
- />
274
- ```
275
-
276
- #### Complete Appearance Structure
277
-
278
- **All auth components** (`SignIn`, `SignUp`, `ForgotPassword`, `ResetPassword`) support hierarchical appearance:
279
-
280
- ```typescript
281
- appearance?: {
282
- container?: string; // Outermost wrapper
283
- card?: string; // Inner card box
284
- header?: {
285
- container?: string; // Header wrapper
286
- title?: string; // Title text
287
- subtitle?: string; // Subtitle text
288
- };
289
- errorBanner?: string; // Error message banner
290
- form?: {
291
- container?: string; // Form wrapper
292
- emailField?: { // Available in SignIn, SignUp, ForgotPassword
293
- container?: string;
294
- label?: string;
295
- input?: string;
296
- };
297
- passwordField?: { // Available in SignIn, SignUp, ResetPassword
298
- container?: string;
299
- label?: string;
300
- input?: string;
301
- forgotPasswordLink?: string; // SignIn only
302
- strengthIndicator?: { // SignUp and ResetPassword
303
- container?: string;
304
- requirement?: string;
305
- };
306
- };
307
- };
308
- button?: string; // Submit button
309
- link?: {
310
- container?: string; // Link section wrapper
311
- text?: string; // Link description text
312
- link?: string; // Actual link element
313
- };
314
- divider?: string; // "or" divider (SignIn, SignUp)
315
- oauth?: { // OAuth section (SignIn, SignUp)
316
- container?: string;
317
- button?: string;
318
- };
319
- }
320
- ```
321
-
322
- ### Text Customization
323
-
324
- All components support full text customization:
325
-
326
- ```tsx
327
- <SignIn
328
- title="Welcome Back!"
329
- subtitle="We're happy to see you again"
330
- emailLabel="Your Email Address"
331
- emailPlaceholder="you@company.com"
332
- passwordLabel="Your Password"
333
- submitButtonText="Login Now"
334
- loadingButtonText="Signing you in..."
335
- signUpText="New to our platform?"
336
- signUpLinkText="Create an account"
337
- dividerText="or continue with"
338
- />
339
-
340
- <ForgotPassword
341
- title="Reset Your Password"
342
- subtitle="Enter your email to receive a reset code"
343
- emailLabel="Email Address"
344
- submitButtonText="Send Reset Code"
345
- backToSignInText="Remember your password?"
346
- successTitle="Check Your Email"
347
- successMessage="We've sent a reset code to your inbox"
348
- />
349
- ```
350
-
351
- ---
352
-
353
- ## Advanced Usage
354
-
355
- ### Complete Component with Custom Logic
356
-
357
- ```tsx
358
- import { SignInForm, useAuth } from '@insforge/react';
359
- import { useState } from 'react';
360
-
361
- function CustomSignIn() {
362
- const { signIn } = useAuth();
363
- const [email, setEmail] = useState('');
364
- const [password, setPassword] = useState('');
365
- const [error, setError] = useState('');
366
- const [loading, setLoading] = useState(false);
367
-
368
- const handleSubmit = async (e: React.FormEvent) => {
369
- e.preventDefault();
370
- setLoading(true);
371
- setError('');
372
-
373
- try {
374
- await signIn(email, password);
375
- // Custom success logic
376
- } catch (err) {
377
- setError(err.message);
378
- } finally {
379
- setLoading(false);
380
- }
381
- };
382
-
383
- return (
384
- <SignInForm
385
- email={email}
386
- password={password}
387
- onEmailChange={setEmail}
388
- onPasswordChange={setPassword}
389
- onSubmit={handleSubmit}
390
- error={error}
391
- loading={loading}
392
- availableProviders={['google', 'github']}
393
- onOAuthClick={(provider) => {
394
- // Custom OAuth logic
395
- }}
396
- />
397
- );
398
- }
399
- ```
400
-
401
- ### Build from Atomic Components
402
-
403
- ```tsx
404
- import {
405
- AuthContainer,
406
- AuthHeader,
407
- AuthFormField,
408
- AuthPasswordField,
409
- AuthSubmitButton,
410
- AuthErrorBanner,
411
- AuthDivider,
412
- AuthOAuthProviders,
413
- AuthLink,
414
- } from '@insforge/react';
415
-
416
- function CompletelyCustomAuth() {
417
- return (
418
- <AuthContainer
419
- appearance={{
420
- containerClassName: "max-w-md",
421
- cardClassName: "bg-white shadow-2xl"
422
- }}
423
- >
424
- <AuthHeader
425
- title="Welcome to MyApp"
426
- subtitle="Sign in to continue"
427
- appearance={{
428
- titleClassName: "text-3xl text-blue-900"
429
- }}
430
- />
431
-
432
- <AuthErrorBanner error={error} />
433
-
434
- <form onSubmit={handleSubmit}>
435
- <AuthFormField
436
- id="email"
437
- type="email"
438
- label="Email"
439
- value={email}
440
- onChange={(e) => setEmail(e.target.value)}
441
- appearance={{
442
- inputClassName: "border-blue-500"
443
- }}
444
- />
445
-
446
- <AuthPasswordField
447
- id="password"
448
- label="Password"
449
- value={password}
450
- onChange={(e) => setPassword(e.target.value)}
451
- emailAuthConfig={config}
452
- showStrengthIndicator
453
- />
454
-
455
- <AuthSubmitButton isLoading={loading}>
456
- Sign In
457
- </AuthSubmitButton>
458
- </form>
459
-
460
- <AuthDivider text="or" />
461
-
462
- <AuthOAuthProviders
463
- providers={['google', 'github', 'discord']}
464
- onClick={handleOAuth}
465
- loading={oauthLoading}
466
- />
467
-
468
- <AuthLink
469
- text="Don't have an account?"
470
- linkText="Sign up"
471
- href="/sign-up"
472
- />
473
- </AuthContainer>
474
- );
475
- }
476
- ```
477
-
478
- ### Route Protection
479
-
480
- ```tsx
481
- import { Protect } from '@insforge/react';
482
-
483
- function Dashboard() {
484
- return (
485
- <div>
486
- <h1>Dashboard</h1>
487
-
488
- {/* Simple protection */}
489
- <Protect redirectTo="/sign-in">
490
- <UserContent />
491
- </Protect>
492
-
493
- {/* Role-based protection */}
494
- <Protect
495
- redirectTo="/unauthorized"
496
- condition={(user) => user.role === 'admin'}
497
- >
498
- <AdminPanel />
499
- </Protect>
500
- </div>
501
- );
502
- }
503
- ```
504
-
505
- ---
506
-
507
- ## TypeScript
508
-
509
- Full TypeScript support with exported types:
510
-
511
- ```tsx
512
- import type {
513
- InsforgeUser,
514
- SignInProps,
515
- SignUpProps,
516
- ForgotPasswordProps,
517
- ResetPasswordProps,
518
- VerifyEmailProps,
519
- SignInAppearance,
520
- SignUpAppearance,
521
- ForgotPasswordAppearance,
522
- ResetPasswordAppearance,
523
- UserButtonProps,
524
- ProtectProps,
525
- ConditionalProps,
526
- InsforgeCallbackProps,
527
- SignInFormProps,
528
- SignUpFormProps,
529
- ForgotPasswordFormProps,
530
- ResetPasswordFormProps,
531
- VerifyEmailStatusProps,
532
- AuthFormFieldProps,
533
- OAuthProvider,
534
- EmailAuthConfig,
535
- InsforgeProviderProps,
536
- GetInsforgeRoutesConfig,
537
- } from '@insforge/react';
538
- ```
539
-
540
- ---
541
-
542
- ## OAuth Providers
543
-
544
- Built-in support for 10+ OAuth providers:
545
- - Google
546
- - GitHub
547
- - Discord
548
- - Apple
549
- - Microsoft
550
- - Facebook
551
- - LinkedIn
552
- - Instagram
553
- - TikTok
554
- - Spotify
555
- - X (Twitter)
556
-
557
- Providers are auto-detected from your backend configuration.
558
-
559
- ---
560
-
561
- ## Validation Utilities
562
-
563
- ```tsx
564
- import { emailSchema, cn } from '@insforge/react/lib';
565
-
566
- // Validate email with Zod
567
- const result = emailSchema.safeParse('user@example.com');
568
-
569
- // Merge Tailwind classes
570
- const className = cn('px-4 py-2', 'bg-blue-500', conditionalClass);
571
- ```
572
-
573
- ---
574
-
575
- ## Available Atomic Components
576
-
577
- Low-level building blocks for complete customization:
578
-
579
- - `<AuthBranding />` - Insforge branding footer
580
- - `<AuthContainer />` - Main container wrapper
581
- - `<AuthHeader />` - Title and subtitle display
582
- - `<AuthErrorBanner />` - Error message display
583
- - `<AuthFormField />` - Standard input field
584
- - `<AuthPasswordField />` - Password input with features
585
- - `<AuthPasswordStrengthIndicator />` - Password checklist
586
- - `<AuthSubmitButton />` - Submit button with states
587
- - `<AuthLink />` - Call-to-action link
588
- - `<AuthDivider />` - Visual separator
589
- - `<AuthOAuthButton />` - Single OAuth provider button
590
- - `<AuthOAuthProviders />` - Smart OAuth grid
591
- - `<AuthVerificationCodeInput />` - 6-digit OTP input
592
- - `<AuthEmailVerificationStep />` - Email verification step with countdown and resend
593
-
594
- ---
595
-
596
- ## Support
597
-
598
- - **Documentation**: https://docs.insforge.dev
599
- - **GitHub Issues**: https://github.com/InsForge/InsForge/issues
600
- - **Discord Community**: https://discord.com/invite/DvBtaEc9Jz
601
-
602
- ## License
603
-
604
- MIT © Insforge
1
+ # @insforge/react
2
+
3
+ **Complete authentication solution for React applications.** Production-ready components with full business logic included.
4
+
5
+ ## Why @insforge/react?
6
+
7
+ ✅ **5-Minute Setup** - One provider + one line of router config = done
8
+ ✅ **Built-in Auth UI** - Use deployed auth pages (like Next.js middleware)
9
+ ✅ **Framework Agnostic** - Works with any React framework
10
+ ✅ **Full TypeScript** - Complete type safety out of the box
11
+ ✅ **Fully Customizable** - Deep styling control when you need it
12
+
13
+ ---
14
+
15
+ ## Quick Start
16
+
17
+ Get authentication working in your React app in 5 minutes.
18
+
19
+ ### 1. Install
20
+
21
+ ```bash
22
+ npm install @insforge/react
23
+ # or
24
+ yarn add @insforge/react
25
+ # or
26
+ pnpm add @insforge/react
27
+ ```
28
+
29
+ ### 2. Setup Provider
30
+
31
+ Wrap your app with `InsforgeProvider`:
32
+
33
+ ```tsx
34
+ // src/main.tsx (Vite) or src/index.tsx (CRA)
35
+ import { StrictMode } from 'react';
36
+ import { createRoot } from 'react-dom/client';
37
+ import { InsforgeProvider } from '@insforge/react';
38
+ import '@insforge/react/styles.css';
39
+ import App from './App';
40
+
41
+ createRoot(document.getElementById('root')!).render(
42
+ <StrictMode>
43
+ <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
44
+ <App />
45
+ </InsforgeProvider>
46
+ </StrictMode>
47
+ );
48
+ ```
49
+
50
+ ### 3. Configure Router (Built-in Auth)
51
+
52
+ ```tsx
53
+ // src/App.tsx
54
+ import { createBrowserRouter, RouterProvider } from 'react-router-dom';
55
+ import { getInsforgeRoutes } from '@insforge/react/router';
56
+ import Home from './pages/Home';
57
+ import Dashboard from './pages/Dashboard';
58
+
59
+ const router = createBrowserRouter([
60
+ { path: '/', element: <Home /> },
61
+
62
+ ...getInsforgeRoutes({
63
+ baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
64
+ builtInAuth: true
65
+ }),
66
+
67
+ { path: '/dashboard', element: <Dashboard /> }
68
+ ]);
69
+
70
+ export default function App() {
71
+ return <RouterProvider router={router} />;
72
+ }
73
+ ```
74
+
75
+ **What this does:**
76
+ - Visiting `/sign-in` → Redirects to `your-project.insforge.app/auth/sign-in`
77
+ - Visiting `/sign-up` → Redirects to `your-project.insforge.app/auth/sign-up`
78
+ - After auth → Redirects back to `/auth/callback` → Goes to dashboard
79
+
80
+ ### 4. Add Auth UI to Your Pages
81
+
82
+ ```tsx
83
+ // src/pages/Home.tsx
84
+ import { SignedIn, SignedOut, UserButton } from '@insforge/react';
85
+
86
+ export default function Home() {
87
+ return (
88
+ <div>
89
+ <nav>
90
+ <SignedOut>
91
+ <a href="/sign-in">Sign In</a>
92
+ </SignedOut>
93
+
94
+ <SignedIn>
95
+ <UserButton afterSignOutUrl="/" />
96
+ </SignedIn>
97
+ </nav>
98
+
99
+ <h1>Welcome to My App!</h1>
100
+ </div>
101
+ );
102
+ }
103
+ ```
104
+
105
+ **That's it!** 🎉 You now have production-ready authentication.
106
+
107
+ ---
108
+
109
+ ## Router Configuration Options
110
+
111
+ ### Built-in Auth (Recommended)
112
+
113
+ Uses your deployed Insforge auth pages (includes all flows):
114
+
115
+ ```tsx
116
+ ...getInsforgeRoutes({
117
+ baseUrl: 'https://your-project.insforge.app',
118
+ builtInAuth: true, // Default
119
+ paths: {
120
+ signIn: '/sign-in', // Sign in page
121
+ signUp: '/sign-up', // Sign up page
122
+ verifyEmail: '/verify-email', // Email verification page
123
+ forgotPassword: '/forgot-password', // Request password reset
124
+ resetPassword: '/reset-password', // Reset password with token
125
+ callback: '/auth/callback' // OAuth callback handler
126
+ }
127
+ })
128
+ ```
129
+
130
+ ### Custom UI Components
131
+
132
+ Use package components with your own styling:
133
+
134
+ ```tsx
135
+ import {
136
+ SignIn,
137
+ SignUp,
138
+ ForgotPassword,
139
+ ResetPassword,
140
+ VerifyEmail
141
+ } from '@insforge/react';
142
+
143
+ const router = createBrowserRouter([
144
+ { path: '/', element: <Home /> },
145
+
146
+ // Still need callback route for OAuth
147
+ ...getInsforgeRoutes({
148
+ baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
149
+ builtInAuth: false // Don't redirect to deployed UI
150
+ }),
151
+
152
+ // Use package components for complete auth flows
153
+ { path: '/sign-in', element: <SignIn afterSignInUrl="/dashboard" /> },
154
+ { path: '/sign-up', element: <SignUp afterSignUpUrl="/dashboard" /> },
155
+ { path: '/forgot-password', element: <ForgotPassword backToSignInUrl="/sign-in" /> },
156
+ { path: '/reset-password', element: <ResetPassword token={searchParams.get('token')} /> },
157
+ { path: '/verify-email', element: <VerifyEmail token={searchParams.get('token')} /> }
158
+ ]);
159
+ ```
160
+
161
+ ### Fully Custom UI
162
+
163
+ Build your own auth pages from scratch:
164
+
165
+ ```tsx
166
+ import { useAuth } from '@insforge/react';
167
+
168
+ function CustomSignIn() {
169
+ const { signIn } = useAuth();
170
+
171
+ const handleSubmit = async (e) => {
172
+ e.preventDefault();
173
+ await signIn(email, password);
174
+ navigate('/dashboard');
175
+ };
176
+
177
+ return <form onSubmit={handleSubmit}>...</form>;
178
+ }
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Core Features
184
+
185
+ ### Components
186
+
187
+ **Pre-built with Business Logic:**
188
+ - `<SignIn />` - Complete sign-in with email/password & OAuth
189
+ - `<SignUp />` - Registration with password validation & email verification
190
+ - `<ForgotPassword />` - Request password reset with email validation
191
+ - `<ResetPassword />` - Reset password with token validation
192
+ - `<VerifyEmail />` - Verify email with automatic token handling
193
+ - `<UserButton />` - User dropdown with sign-out
194
+ - `<Protect />` - Route protection wrapper
195
+ - `<SignedIn>` / `<SignedOut>` - Conditional rendering
196
+ - `<InsforgeCallback />` - OAuth callback handler
197
+
198
+ **Form Components (Pure UI):**
199
+ - `<SignInForm />` - Sign-in UI without logic
200
+ - `<SignUpForm />` - Sign-up UI without logic
201
+ - `<ForgotPasswordForm />` - Password reset request UI
202
+ - `<ResetPasswordForm />` - Password reset with token UI
203
+ - `<VerifyEmailStatus />` - Email verification status UI
204
+
205
+ **Atomic Components (14 total):**
206
+ - `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, `<AuthEmailVerificationStep />`, etc.
207
+
208
+ ### Hooks
209
+
210
+ ```tsx
211
+ const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
212
+ const { user, updateUser, isLoaded } = useUser();
213
+ const { oauthProviders, authConfig, isLoaded } = usePublicAuthConfig();
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Customization
219
+
220
+ ### Basic Styling
221
+
222
+ All components support `appearance` props:
223
+
224
+ ```tsx
225
+ <SignIn
226
+ appearance={{
227
+ container: "max-w-lg",
228
+ card: "bg-white shadow-2xl",
229
+ button: "bg-blue-600 hover:bg-blue-700"
230
+ }}
231
+ />
232
+
233
+ // Works with all auth components
234
+ <ForgotPassword
235
+ appearance={{
236
+ card: "bg-gradient-to-br from-indigo-50 to-white",
237
+ button: "bg-indigo-600 hover:bg-indigo-700"
238
+ }}
239
+ />
240
+ ```
241
+
242
+ ### Deep Customization (Hierarchical Appearance)
243
+
244
+ Style nested components through hierarchical structure:
245
+
246
+ ```tsx
247
+ <SignIn
248
+ appearance={{
249
+ card: "bg-gradient-to-br from-blue-50 to-white shadow-2xl",
250
+ header: {
251
+ title: "text-3xl font-bold text-purple-900",
252
+ subtitle: "text-purple-600"
253
+ },
254
+ form: {
255
+ emailField: {
256
+ label: "text-gray-800 font-semibold",
257
+ input: "border-purple-300 focus:border-purple-500 rounded-lg"
258
+ },
259
+ passwordField: {
260
+ input: "border-purple-300 focus:border-purple-500 rounded-lg",
261
+ forgotPasswordLink: "text-purple-600 hover:text-purple-800"
262
+ }
263
+ },
264
+ button: "bg-purple-600 hover:bg-purple-700 rounded-lg h-12",
265
+ link: {
266
+ text: "text-gray-600",
267
+ link: "text-purple-600 hover:text-purple-800 font-semibold"
268
+ },
269
+ oauth: {
270
+ button: "border-2 hover:bg-gray-50 rounded-xl"
271
+ }
272
+ }}
273
+ />
274
+ ```
275
+
276
+ #### Complete Appearance Structure
277
+
278
+ **All auth components** (`SignIn`, `SignUp`, `ForgotPassword`, `ResetPassword`) support hierarchical appearance:
279
+
280
+ ```typescript
281
+ appearance?: {
282
+ container?: string; // Outermost wrapper
283
+ card?: string; // Inner card box
284
+ header?: {
285
+ container?: string; // Header wrapper
286
+ title?: string; // Title text
287
+ subtitle?: string; // Subtitle text
288
+ };
289
+ errorBanner?: string; // Error message banner
290
+ form?: {
291
+ container?: string; // Form wrapper
292
+ emailField?: { // Available in SignIn, SignUp, ForgotPassword
293
+ container?: string;
294
+ label?: string;
295
+ input?: string;
296
+ };
297
+ passwordField?: { // Available in SignIn, SignUp, ResetPassword
298
+ container?: string;
299
+ label?: string;
300
+ input?: string;
301
+ forgotPasswordLink?: string; // SignIn only
302
+ strengthIndicator?: { // SignUp and ResetPassword
303
+ container?: string;
304
+ requirement?: string;
305
+ };
306
+ };
307
+ };
308
+ button?: string; // Submit button
309
+ link?: {
310
+ container?: string; // Link section wrapper
311
+ text?: string; // Link description text
312
+ link?: string; // Actual link element
313
+ };
314
+ divider?: string; // "or" divider (SignIn, SignUp)
315
+ oauth?: { // OAuth section (SignIn, SignUp)
316
+ container?: string;
317
+ button?: string;
318
+ };
319
+ }
320
+ ```
321
+
322
+ ### Text Customization
323
+
324
+ All components support full text customization:
325
+
326
+ ```tsx
327
+ <SignIn
328
+ title="Welcome Back!"
329
+ subtitle="We're happy to see you again"
330
+ emailLabel="Your Email Address"
331
+ emailPlaceholder="you@company.com"
332
+ passwordLabel="Your Password"
333
+ submitButtonText="Login Now"
334
+ loadingButtonText="Signing you in..."
335
+ signUpText="New to our platform?"
336
+ signUpLinkText="Create an account"
337
+ dividerText="or continue with"
338
+ />
339
+
340
+ <ForgotPassword
341
+ title="Reset Your Password"
342
+ subtitle="Enter your email to receive a reset code"
343
+ emailLabel="Email Address"
344
+ submitButtonText="Send Reset Code"
345
+ backToSignInText="Remember your password?"
346
+ successTitle="Check Your Email"
347
+ successMessage="We've sent a reset code to your inbox"
348
+ />
349
+ ```
350
+
351
+ ---
352
+
353
+ ## Advanced Usage
354
+
355
+ ### Complete Component with Custom Logic
356
+
357
+ ```tsx
358
+ import { SignInForm, useAuth } from '@insforge/react';
359
+ import { useState } from 'react';
360
+
361
+ function CustomSignIn() {
362
+ const { signIn } = useAuth();
363
+ const [email, setEmail] = useState('');
364
+ const [password, setPassword] = useState('');
365
+ const [error, setError] = useState('');
366
+ const [loading, setLoading] = useState(false);
367
+
368
+ const handleSubmit = async (e: React.FormEvent) => {
369
+ e.preventDefault();
370
+ setLoading(true);
371
+ setError('');
372
+
373
+ try {
374
+ await signIn(email, password);
375
+ // Custom success logic
376
+ } catch (err) {
377
+ setError(err.message);
378
+ } finally {
379
+ setLoading(false);
380
+ }
381
+ };
382
+
383
+ return (
384
+ <SignInForm
385
+ email={email}
386
+ password={password}
387
+ onEmailChange={setEmail}
388
+ onPasswordChange={setPassword}
389
+ onSubmit={handleSubmit}
390
+ error={error}
391
+ loading={loading}
392
+ availableProviders={['google', 'github']}
393
+ onOAuthClick={(provider) => {
394
+ // Custom OAuth logic
395
+ }}
396
+ />
397
+ );
398
+ }
399
+ ```
400
+
401
+ ### Build from Atomic Components
402
+
403
+ ```tsx
404
+ import {
405
+ AuthContainer,
406
+ AuthHeader,
407
+ AuthFormField,
408
+ AuthPasswordField,
409
+ AuthSubmitButton,
410
+ AuthErrorBanner,
411
+ AuthDivider,
412
+ AuthOAuthProviders,
413
+ AuthLink,
414
+ } from '@insforge/react';
415
+
416
+ function CompletelyCustomAuth() {
417
+ return (
418
+ <AuthContainer
419
+ appearance={{
420
+ containerClassName: "max-w-md",
421
+ cardClassName: "bg-white shadow-2xl"
422
+ }}
423
+ >
424
+ <AuthHeader
425
+ title="Welcome to MyApp"
426
+ subtitle="Sign in to continue"
427
+ appearance={{
428
+ titleClassName: "text-3xl text-blue-900"
429
+ }}
430
+ />
431
+
432
+ <AuthErrorBanner error={error} />
433
+
434
+ <form onSubmit={handleSubmit}>
435
+ <AuthFormField
436
+ id="email"
437
+ type="email"
438
+ label="Email"
439
+ value={email}
440
+ onChange={(e) => setEmail(e.target.value)}
441
+ appearance={{
442
+ inputClassName: "border-blue-500"
443
+ }}
444
+ />
445
+
446
+ <AuthPasswordField
447
+ id="password"
448
+ label="Password"
449
+ value={password}
450
+ onChange={(e) => setPassword(e.target.value)}
451
+ authConfig={config}
452
+ showStrengthIndicator
453
+ />
454
+
455
+ <AuthSubmitButton isLoading={loading}>
456
+ Sign In
457
+ </AuthSubmitButton>
458
+ </form>
459
+
460
+ <AuthDivider text="or" />
461
+
462
+ <AuthOAuthProviders
463
+ providers={['google', 'github', 'discord']}
464
+ onClick={handleOAuth}
465
+ loading={oauthLoading}
466
+ />
467
+
468
+ <AuthLink
469
+ text="Don't have an account?"
470
+ linkText="Sign up"
471
+ href="/sign-up"
472
+ />
473
+ </AuthContainer>
474
+ );
475
+ }
476
+ ```
477
+
478
+ ### Route Protection
479
+
480
+ ```tsx
481
+ import { Protect } from '@insforge/react';
482
+
483
+ function Dashboard() {
484
+ return (
485
+ <div>
486
+ <h1>Dashboard</h1>
487
+
488
+ {/* Simple protection */}
489
+ <Protect redirectTo="/sign-in">
490
+ <UserContent />
491
+ </Protect>
492
+
493
+ {/* Role-based protection */}
494
+ <Protect
495
+ redirectTo="/unauthorized"
496
+ condition={(user) => user.role === 'admin'}
497
+ >
498
+ <AdminPanel />
499
+ </Protect>
500
+ </div>
501
+ );
502
+ }
503
+ ```
504
+
505
+ ---
506
+
507
+ ## TypeScript
508
+
509
+ Full TypeScript support with exported types:
510
+
511
+ ```tsx
512
+ import type {
513
+ InsforgeUser,
514
+ SignInProps,
515
+ SignUpProps,
516
+ ForgotPasswordProps,
517
+ ResetPasswordProps,
518
+ VerifyEmailProps,
519
+ SignInAppearance,
520
+ SignUpAppearance,
521
+ ForgotPasswordAppearance,
522
+ ResetPasswordAppearance,
523
+ UserButtonProps,
524
+ ProtectProps,
525
+ ConditionalProps,
526
+ InsforgeCallbackProps,
527
+ SignInFormProps,
528
+ SignUpFormProps,
529
+ ForgotPasswordFormProps,
530
+ ResetPasswordFormProps,
531
+ VerifyEmailStatusProps,
532
+ AuthFormFieldProps,
533
+ OAuthProvider,
534
+ EmailAuthConfig,
535
+ InsforgeProviderProps,
536
+ GetInsforgeRoutesConfig,
537
+ } from '@insforge/react';
538
+ ```
539
+
540
+ ---
541
+
542
+ ## OAuth Providers
543
+
544
+ Built-in support for 10+ OAuth providers:
545
+ - Google
546
+ - GitHub
547
+ - Discord
548
+ - Apple
549
+ - Microsoft
550
+ - Facebook
551
+ - LinkedIn
552
+ - Instagram
553
+ - TikTok
554
+ - Spotify
555
+ - X (Twitter)
556
+
557
+ Providers are auto-detected from your backend configuration.
558
+
559
+ ---
560
+
561
+ ## Validation Utilities
562
+
563
+ ```tsx
564
+ import { emailSchema, cn } from '@insforge/react/lib';
565
+
566
+ // Validate email with Zod
567
+ const result = emailSchema.safeParse('user@example.com');
568
+
569
+ // Merge Tailwind classes
570
+ const className = cn('px-4 py-2', 'bg-blue-500', conditionalClass);
571
+ ```
572
+
573
+ ---
574
+
575
+ ## Available Atomic Components
576
+
577
+ Low-level building blocks for complete customization:
578
+
579
+ - `<AuthBranding />` - Insforge branding footer
580
+ - `<AuthContainer />` - Main container wrapper
581
+ - `<AuthHeader />` - Title and subtitle display
582
+ - `<AuthErrorBanner />` - Error message display
583
+ - `<AuthFormField />` - Standard input field
584
+ - `<AuthPasswordField />` - Password input with features
585
+ - `<AuthPasswordStrengthIndicator />` - Password checklist
586
+ - `<AuthSubmitButton />` - Submit button with states
587
+ - `<AuthLink />` - Call-to-action link
588
+ - `<AuthDivider />` - Visual separator
589
+ - `<AuthOAuthButton />` - Single OAuth provider button
590
+ - `<AuthOAuthProviders />` - Smart OAuth grid
591
+ - `<AuthVerificationCodeInput />` - 6-digit OTP input
592
+ - `<AuthEmailVerificationStep />` - Email verification step with countdown and resend
593
+
594
+ ---
595
+
596
+ ## Support
597
+
598
+ - **Documentation**: https://docs.insforge.dev
599
+ - **GitHub Issues**: https://github.com/InsForge/InsForge/issues
600
+ - **Discord Community**: https://discord.com/invite/DvBtaEc9Jz
601
+
602
+ ## License
603
+
604
+ MIT © Insforge