@insforge/nextjs 0.10.2 → 0.10.4
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 +335 -330
- package/dist/api/route-handlers.d.ts +63 -4
- package/dist/client-boundary/hooks.d.ts +9 -46
- package/dist/client-boundary/provider.d.ts +43 -0
- package/dist/esm/api/index.js.map +1 -1
- package/dist/esm/api/route-handlers.js +14 -45
- package/dist/esm/api/route-handlers.js.map +1 -1
- package/dist/esm/client-boundary/components.js.map +1 -1
- package/dist/esm/client-boundary/hooks.js.map +1 -1
- package/dist/esm/client-boundary/provider.js +3 -3
- package/dist/esm/client-boundary/provider.js.map +1 -1
- package/dist/esm/index.js +5 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/middleware/InsforgeMiddleware.js +1 -1
- package/dist/esm/middleware/InsforgeMiddleware.js.map +1 -1
- package/dist/esm/middleware/index.js +1 -3
- package/dist/esm/middleware/index.js.map +1 -1
- package/dist/esm/navigation/NextNavigationAdapter.js.map +1 -1
- package/dist/esm/navigation/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/middleware/InsforgeMiddleware.d.ts +119 -1
- package/dist/navigation/NextNavigationAdapter.d.ts +5 -0
- package/package.json +58 -60
- package/src/styles.css +1 -1
package/README.md
CHANGED
|
@@ -1,330 +1,335 @@
|
|
|
1
|
-
# @insforge/nextjs
|
|
2
|
-
|
|
3
|
-
**Zero-configuration authentication for Next.js** using Insforge backend. Get production-ready auth in 5 minutes.
|
|
4
|
-
|
|
5
|
-
## Why @insforge/nextjs?
|
|
6
|
-
|
|
7
|
-
✅ **Built-in Auth Pages** - Backend-hosted UI, no React code needed
|
|
8
|
-
✅ **5-Minute Setup** - Provider + API route + callback + middleware = done
|
|
9
|
-
✅ **Full SSR Support** - Works with Next.js App Router and Server Components
|
|
10
|
-
✅ **Auto OAuth** - 11 providers configured from backend automatically
|
|
11
|
-
✅ **TypeScript First** - Complete type safety out of the box
|
|
12
|
-
|
|
13
|
-
**Need custom UI?** Scroll to [Customization](#customization) for custom components and styling.
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install @insforge/nextjs
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Quick Start
|
|
24
|
-
|
|
25
|
-
### 1. Setup Provider
|
|
26
|
-
|
|
27
|
-
Wrap your app with `InsforgeProvider` in the root layout:
|
|
28
|
-
|
|
29
|
-
```tsx
|
|
30
|
-
// app/layout.tsx
|
|
31
|
-
import { InsforgeProvider } from '@insforge/nextjs';
|
|
32
|
-
|
|
33
|
-
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
34
|
-
return (
|
|
35
|
-
<html lang="en">
|
|
36
|
-
<body>
|
|
37
|
-
<InsforgeProvider
|
|
38
|
-
baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}
|
|
39
|
-
afterSignInUrl="/dashboard"
|
|
40
|
-
>
|
|
41
|
-
{children}
|
|
42
|
-
</InsforgeProvider>
|
|
43
|
-
</body>
|
|
44
|
-
</html>
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
> **Auto-styled**: Component styles are automatically injected. No CSS imports needed!
|
|
50
|
-
|
|
51
|
-
### 2. Create API Route
|
|
52
|
-
|
|
53
|
-
Create an API route to sync tokens to HTTP-only cookies (enables SSR):
|
|
54
|
-
|
|
55
|
-
```tsx
|
|
56
|
-
// app/api/auth/route.ts
|
|
57
|
-
import { createAuthRouteHandlers } from '@insforge/nextjs/api';
|
|
58
|
-
|
|
59
|
-
const handlers = createAuthRouteHandlers({
|
|
60
|
-
baseUrl: process.env.INSFORGE_BASE_URL || process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!,
|
|
61
|
-
cookieName: 'insforge_token',
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
export const POST = handlers.POST;
|
|
65
|
-
export const GET = handlers.GET;
|
|
66
|
-
export const DELETE = handlers.DELETE;
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**What it does:**
|
|
70
|
-
|
|
71
|
-
- `
|
|
72
|
-
- `
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
↓
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
- `
|
|
214
|
-
- `
|
|
215
|
-
- `
|
|
216
|
-
- `
|
|
217
|
-
- `
|
|
218
|
-
- `
|
|
219
|
-
- `
|
|
220
|
-
- `
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
//
|
|
263
|
-
<Protect condition={(user) => user.
|
|
264
|
-
<
|
|
265
|
-
</Protect>
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
1
|
+
# @insforge/nextjs
|
|
2
|
+
|
|
3
|
+
**Zero-configuration authentication for Next.js** using Insforge backend. Get production-ready auth in 5 minutes.
|
|
4
|
+
|
|
5
|
+
## Why @insforge/nextjs?
|
|
6
|
+
|
|
7
|
+
✅ **Built-in Auth Pages** - Backend-hosted UI, no React code needed
|
|
8
|
+
✅ **5-Minute Setup** - Provider + API route + callback + middleware = done
|
|
9
|
+
✅ **Full SSR Support** - Works with Next.js App Router and Server Components
|
|
10
|
+
✅ **Auto OAuth** - 11 providers configured from backend automatically
|
|
11
|
+
✅ **TypeScript First** - Complete type safety out of the box
|
|
12
|
+
|
|
13
|
+
**Need custom UI?** Scroll to [Customization](#customization) for custom components and styling.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @insforge/nextjs
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Setup Provider
|
|
26
|
+
|
|
27
|
+
Wrap your app with `InsforgeProvider` in the root layout:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
// app/layout.tsx
|
|
31
|
+
import { InsforgeProvider } from '@insforge/nextjs';
|
|
32
|
+
|
|
33
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
34
|
+
return (
|
|
35
|
+
<html lang="en">
|
|
36
|
+
<body>
|
|
37
|
+
<InsforgeProvider
|
|
38
|
+
baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}
|
|
39
|
+
afterSignInUrl="/dashboard"
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
</InsforgeProvider>
|
|
43
|
+
</body>
|
|
44
|
+
</html>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> **Auto-styled**: Component styles are automatically injected. No CSS imports needed!
|
|
50
|
+
|
|
51
|
+
### 2. Create API Route
|
|
52
|
+
|
|
53
|
+
Create an API route to sync tokens to HTTP-only cookies (enables SSR):
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
// app/api/auth/route.ts
|
|
57
|
+
import { createAuthRouteHandlers } from '@insforge/nextjs/api';
|
|
58
|
+
|
|
59
|
+
const handlers = createAuthRouteHandlers({
|
|
60
|
+
baseUrl: process.env.INSFORGE_BASE_URL || process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!,
|
|
61
|
+
cookieName: 'insforge_token',
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export const POST = handlers.POST;
|
|
65
|
+
export const GET = handlers.GET;
|
|
66
|
+
export const DELETE = handlers.DELETE;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**What it does:**
|
|
70
|
+
|
|
71
|
+
- `POST /api/auth` - Syncs localStorage token to HTTP-only cookie
|
|
72
|
+
- `GET /api/auth` - Retrieves user data server-side
|
|
73
|
+
- `DELETE /api/auth` - Clears auth cookie on sign out
|
|
74
|
+
|
|
75
|
+
### 3. Setup Middleware
|
|
76
|
+
|
|
77
|
+
Protect routes with middleware:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
// middleware.ts
|
|
81
|
+
import { InsforgeMiddleware } from '@insforge/nextjs/middleware';
|
|
82
|
+
|
|
83
|
+
export default InsforgeMiddleware({
|
|
84
|
+
baseUrl: process.env.INSFORGE_BASE_URL!,
|
|
85
|
+
publicRoutes: ['/auth/callback', '/'],
|
|
86
|
+
cookieName: 'insforge_token',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
export const config = {
|
|
90
|
+
matcher: [
|
|
91
|
+
'/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**What it does:**
|
|
97
|
+
|
|
98
|
+
- Redirects unauthenticated users to backend auth pages
|
|
99
|
+
- Verifies tokens server-side
|
|
100
|
+
- Allows public routes without auth
|
|
101
|
+
|
|
102
|
+
### 4. Use Hooks & Components
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// app/page.tsx
|
|
106
|
+
import { SignedIn, SignedOut, UserButton } from '@insforge/nextjs';
|
|
107
|
+
|
|
108
|
+
export default function Home() {
|
|
109
|
+
return (
|
|
110
|
+
<div>
|
|
111
|
+
<SignedOut>
|
|
112
|
+
<a href="/sign-in">Sign In</a>
|
|
113
|
+
</SignedOut>
|
|
114
|
+
|
|
115
|
+
<SignedIn>
|
|
116
|
+
<UserButton afterSignOutUrl="/" />
|
|
117
|
+
<h1>Welcome back!</h1>
|
|
118
|
+
</SignedIn>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Available Hooks:**
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { useAuth, useUser } from '@insforge/nextjs';
|
|
128
|
+
|
|
129
|
+
function Component() {
|
|
130
|
+
const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
|
|
131
|
+
const { user, updateUser } = useUser();
|
|
132
|
+
|
|
133
|
+
return <div>Email: {user?.email}</div>;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**That's it!** 🎉 Your app now has production-ready authentication.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## How It Works
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
1. User clicks "Sign In" → Middleware redirects to backend auth page
|
|
145
|
+
↓
|
|
146
|
+
2. User signs in on backend (https://your-project.insforge.app/auth/sign-in)
|
|
147
|
+
↓
|
|
148
|
+
3. Backend redirects: yourapp.com?access_token=xxx&user_id=xxx...
|
|
149
|
+
↓
|
|
150
|
+
4. SDK auto-detects URL parameters:
|
|
151
|
+
- Stores token in localStorage
|
|
152
|
+
- Provider automatically reloads auth state
|
|
153
|
+
- Token syncs to HTTP-only cookie (via API route)
|
|
154
|
+
↓
|
|
155
|
+
5. User sees dashboard with authenticated state
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Two-Storage Architecture:**
|
|
159
|
+
|
|
160
|
+
- **localStorage**: Client-side token access (hooks, components, SDK)
|
|
161
|
+
- **HTTP-only cookie**: Server-side token access (middleware, SSR)
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Customization
|
|
166
|
+
|
|
167
|
+
### Custom Auth Pages
|
|
168
|
+
|
|
169
|
+
Want custom branding? Create custom auth pages instead of using built-in pages:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
// app/sign-in/page.tsx
|
|
173
|
+
'use client';
|
|
174
|
+
|
|
175
|
+
import { SignIn } from '@insforge/nextjs';
|
|
176
|
+
import { useRouter } from 'next/navigation';
|
|
177
|
+
|
|
178
|
+
export default function SignInPage() {
|
|
179
|
+
const router = useRouter();
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
<div className="min-h-screen flex items-center justify-center bg-gray-50">
|
|
183
|
+
<SignIn
|
|
184
|
+
afterSignInUrl="/dashboard"
|
|
185
|
+
onSuccess={(user) => {
|
|
186
|
+
console.log('Signed in:', user);
|
|
187
|
+
router.push('/dashboard');
|
|
188
|
+
}}
|
|
189
|
+
/>
|
|
190
|
+
</div>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Additional Auth Components:**
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
// Password reset flow
|
|
199
|
+
import { ForgotPassword, ResetPassword, VerifyEmail } from '@insforge/nextjs';
|
|
200
|
+
|
|
201
|
+
// app/forgot-password/page.tsx
|
|
202
|
+
<ForgotPassword backToSignInUrl="/sign-in" />
|
|
203
|
+
|
|
204
|
+
// app/reset-password/page.tsx (with token from URL)
|
|
205
|
+
<ResetPassword token={token} backToSignInUrl="/sign-in" />
|
|
206
|
+
|
|
207
|
+
// app/verify-email/page.tsx (with token from URL)
|
|
208
|
+
<VerifyEmail token={token} />
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Available Atomic Components:**
|
|
212
|
+
|
|
213
|
+
- `AuthContainer` - Main form container
|
|
214
|
+
- `AuthHeader` - Title and subtitle
|
|
215
|
+
- `AuthFormField` - Standard input field
|
|
216
|
+
- `AuthPasswordField` - Password field with visibility toggle
|
|
217
|
+
- `AuthPasswordStrengthIndicator` - Password requirement checklist
|
|
218
|
+
- `AuthSubmitButton` - Submit button with loading states
|
|
219
|
+
- `AuthErrorBanner` - Error message display
|
|
220
|
+
- `AuthDivider` - Visual separator
|
|
221
|
+
- `AuthOAuthProviders` - OAuth provider buttons grid
|
|
222
|
+
- `AuthOAuthButton` - Individual OAuth button
|
|
223
|
+
- `AuthVerificationCodeInput` - OTP/2FA code input
|
|
224
|
+
- `AuthLink` - Navigation link
|
|
225
|
+
- `AuthBranding` - Insforge branding footer
|
|
226
|
+
|
|
227
|
+
### Server-Side Usage
|
|
228
|
+
|
|
229
|
+
Access auth data in Server Components:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
// app/dashboard/page.tsx (Server Component)
|
|
233
|
+
import { headers } from 'next/headers';
|
|
234
|
+
import { getAuthUserId, getAuthToken } from '@insforge/nextjs/middleware';
|
|
235
|
+
import { createClient } from '@insforge/sdk';
|
|
236
|
+
|
|
237
|
+
export default async function Dashboard() {
|
|
238
|
+
const userId = getAuthUserId(headers());
|
|
239
|
+
const token = getAuthToken(headers());
|
|
240
|
+
|
|
241
|
+
if (!userId) {
|
|
242
|
+
return <div>Not authenticated</div>;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Use SDK for server-side data fetching
|
|
246
|
+
const insforge = createClient({
|
|
247
|
+
baseUrl: process.env.INSFORGE_BASE_URL!,
|
|
248
|
+
edgeFunctionToken: token || undefined,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const { data: userData } = await insforge.auth.getCurrentUser();
|
|
252
|
+
|
|
253
|
+
return <div>Welcome, {userData?.user.email}</div>;
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Conditional Rendering
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
import { Protect } from '@insforge/nextjs';
|
|
261
|
+
|
|
262
|
+
// Role-based access
|
|
263
|
+
<Protect condition={(user) => user.role === 'admin'}>
|
|
264
|
+
<AdminPanel />
|
|
265
|
+
</Protect>
|
|
266
|
+
|
|
267
|
+
// Custom logic
|
|
268
|
+
<Protect condition={(user) => user.emailVerified}>
|
|
269
|
+
<VerifiedUserFeature />
|
|
270
|
+
</Protect>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Auth Change Callback
|
|
274
|
+
|
|
275
|
+
Track authentication events:
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
<InsforgeProvider
|
|
279
|
+
baseUrl={baseUrl}
|
|
280
|
+
onAuthChange={(user) => {
|
|
281
|
+
if (user) {
|
|
282
|
+
analytics.identify(user.id);
|
|
283
|
+
} else {
|
|
284
|
+
analytics.reset();
|
|
285
|
+
}
|
|
286
|
+
}}
|
|
287
|
+
/>
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Local Development
|
|
293
|
+
|
|
294
|
+
During local development, backend typically runs on a different port:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
# .env.local
|
|
298
|
+
NEXT_PUBLIC_INSFORGE_BASE_URL=http://localhost:7130
|
|
299
|
+
INSFORGE_BASE_URL=http://localhost:7130
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## TypeScript
|
|
305
|
+
|
|
306
|
+
Full TypeScript support with exported types:
|
|
307
|
+
|
|
308
|
+
```tsx
|
|
309
|
+
import type {
|
|
310
|
+
InsforgeUser,
|
|
311
|
+
InsforgeCallbackProps,
|
|
312
|
+
SignInProps,
|
|
313
|
+
SignUpProps,
|
|
314
|
+
ForgotPasswordProps,
|
|
315
|
+
ResetPasswordProps,
|
|
316
|
+
VerifyEmailProps,
|
|
317
|
+
SignInAppearance,
|
|
318
|
+
SignUpAppearance,
|
|
319
|
+
UserButtonProps,
|
|
320
|
+
ProtectProps,
|
|
321
|
+
OAuthProvider,
|
|
322
|
+
} from '@insforge/nextjs';
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Support
|
|
328
|
+
|
|
329
|
+
- **Documentation**: https://docs.insforge.dev
|
|
330
|
+
- **GitHub Issues**: https://github.com/InsForge/InsForge/issues
|
|
331
|
+
- **Discord Community**: https://discord.com/invite/DvBtaEc9Jz
|
|
332
|
+
|
|
333
|
+
## License
|
|
334
|
+
|
|
335
|
+
MIT
|