@ascendkit/nextjs 0.3.4 → 0.3.6
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
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# @ascendkit/nextjs
|
|
2
|
+
|
|
3
|
+
Authentication, email templates, surveys, and user journeys for Next.js and React apps.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ascendkit/nextjs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires `next >= 14` and `react >= 18` as peer dependencies. Set up environment variables with the CLI:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @ascendkit/cli
|
|
15
|
+
ascendkit init
|
|
16
|
+
ascendkit set-env pk_dev_your_public_key
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Auth setup (4 steps)
|
|
20
|
+
|
|
21
|
+
### 1. Create the auth runtime
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// lib/auth.ts
|
|
25
|
+
import { createAscendKitAuthRuntime } from "@ascendkit/nextjs/server";
|
|
26
|
+
|
|
27
|
+
export const authRuntime = createAscendKitAuthRuntime();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Reads `ASCENDKIT_ENV_KEY`, `ASCENDKIT_SECRET_KEY`, and `ASCENDKIT_API_URL` from your environment automatically.
|
|
31
|
+
|
|
32
|
+
### 2. Add the API route
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
// app/api/auth/[...all]/route.ts
|
|
36
|
+
import { authRuntime } from "@/lib/auth";
|
|
37
|
+
import { createAuthRouteHandlers } from "@ascendkit/nextjs/server";
|
|
38
|
+
|
|
39
|
+
export const { GET, POST } = createAuthRouteHandlers(authRuntime);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Add the provider
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
// app/layout.tsx
|
|
46
|
+
import { AscendKitProvider } from "@ascendkit/nextjs";
|
|
47
|
+
|
|
48
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
49
|
+
return (
|
|
50
|
+
<html lang="en">
|
|
51
|
+
<body>
|
|
52
|
+
<AscendKitProvider>{children}</AscendKitProvider>
|
|
53
|
+
</body>
|
|
54
|
+
</html>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 4. Add auth pages
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
// app/login/page.tsx
|
|
63
|
+
import { Login } from "@ascendkit/nextjs";
|
|
64
|
+
|
|
65
|
+
export default function LoginPage() {
|
|
66
|
+
return <Login onSuccess={() => window.location.href = "/dashboard"} />;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
// app/signup/page.tsx
|
|
72
|
+
import { SignUp } from "@ascendkit/nextjs";
|
|
73
|
+
|
|
74
|
+
export default function SignUpPage() {
|
|
75
|
+
return <SignUp onSuccess={() => window.location.href = "/dashboard"} />;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Social login buttons appear automatically when providers are enabled via the CLI or portal.
|
|
80
|
+
|
|
81
|
+
## Components
|
|
82
|
+
|
|
83
|
+
All components render inside `<AscendKitProvider>`.
|
|
84
|
+
|
|
85
|
+
| Component | Description |
|
|
86
|
+
|-----------|-------------|
|
|
87
|
+
| `<Login />` | Sign-in form (email/password + social) |
|
|
88
|
+
| `<SignUp />` | Sign-up form (email/password + social) |
|
|
89
|
+
| `<AscendKitAuthCard />` | All-in-one auth card (`view="SIGN_IN"`, `"SIGN_UP"`, `"FORGOT_PASSWORD"`) |
|
|
90
|
+
| `<AscendKitUserButton />` | User avatar with sign-out dropdown |
|
|
91
|
+
| `<SignInButton />` | Opens auth modal or redirects (`mode="modal"` or `"redirect"`) |
|
|
92
|
+
| `<SignUpButton />` | Opens auth modal or redirects |
|
|
93
|
+
| `<SocialButton provider="google" />` | Individual social login button |
|
|
94
|
+
| `<SignedIn>` | Renders children only when authenticated |
|
|
95
|
+
| `<SignedOut>` | Renders children only when not authenticated |
|
|
96
|
+
| `<AuthLoading>` | Renders children while auth state is loading |
|
|
97
|
+
|
|
98
|
+
## Hooks
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { useAscendKit } from "@ascendkit/nextjs";
|
|
102
|
+
|
|
103
|
+
const { user, isLoaded, isAuthenticated, signOut } = useAscendKit();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { useAuthModal } from "@ascendkit/nextjs";
|
|
108
|
+
|
|
109
|
+
const { isOpen, view, open, close } = useAuthModal();
|
|
110
|
+
open("sign-in"); // or "sign-up"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { useAnalytics } from "@ascendkit/nextjs";
|
|
115
|
+
|
|
116
|
+
const { track, flush } = useAnalytics();
|
|
117
|
+
track("checkout.completed", { total: 99.99 });
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Access tokens (frontend → backend)
|
|
121
|
+
|
|
122
|
+
If your app has a separate backend, use access tokens to authenticate API calls from the browser.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// app/api/access-token/route.ts
|
|
126
|
+
import { authRuntime } from "@/lib/auth";
|
|
127
|
+
import { createAccessTokenHandler } from "@ascendkit/nextjs/server";
|
|
128
|
+
|
|
129
|
+
export const GET = createAccessTokenHandler({ authRuntime });
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
import { useAccessToken } from "@ascendkit/nextjs";
|
|
134
|
+
|
|
135
|
+
const { getAccessToken } = useAccessToken();
|
|
136
|
+
const token = await getAccessToken();
|
|
137
|
+
fetch("https://api.example.com/data", {
|
|
138
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Tokens are short-lived RS256 JWTs, cached in memory, and auto-refreshed. Verify on any backend using AscendKit's JWKS endpoint or the [Python SDK](https://ascendkit.dev/docs/python).
|
|
143
|
+
|
|
144
|
+
## Server-side analytics
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { Analytics } from "@ascendkit/nextjs/server";
|
|
148
|
+
|
|
149
|
+
const analytics = new Analytics();
|
|
150
|
+
analytics.track("usr_456", "checkout.completed", { total: 99.99 });
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Environment variables
|
|
154
|
+
|
|
155
|
+
| Variable | Side | Description |
|
|
156
|
+
|----------|------|-------------|
|
|
157
|
+
| `ASCENDKIT_ENV_KEY` | Server | Project public key |
|
|
158
|
+
| `NEXT_PUBLIC_ASCENDKIT_ENV_KEY` | Client | Same key, exposed to browser |
|
|
159
|
+
| `ASCENDKIT_SECRET_KEY` | Server | Secret key (analytics, admin) |
|
|
160
|
+
| `ASCENDKIT_API_URL` | Server | Backend URL (default: `https://api.ascendkit.dev`) |
|
|
161
|
+
| `NEXT_PUBLIC_ASCENDKIT_API_URL` | Client | Same URL, exposed to browser |
|
|
162
|
+
| `APP_URL` | Server | Public app URL for auth callbacks |
|
|
163
|
+
|
|
164
|
+
## Other React frameworks
|
|
165
|
+
|
|
166
|
+
The React hooks and components work in any React 18+ framework (Vite, Remix, Astro). The server-side auth runtime (`createAscendKitAuthRuntime`, `createAuthRouteHandlers`) requires Next.js.
|
|
167
|
+
|
|
168
|
+
## Docs
|
|
169
|
+
|
|
170
|
+
- [Full documentation](https://ascendkit.dev/docs)
|
|
171
|
+
- [Next.js integration guide](https://ascendkit.dev/docs/integration)
|
|
172
|
+
- [Python SDK](https://ascendkit.dev/docs/python)
|
|
173
|
+
- [LLM-friendly docs](https://ascendkit.dev/docs/llms.txt)
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-card.d.ts","sourceRoot":"","sources":["../../src/components/auth-card.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAK1E,UAAU,sBAAuB,SAAQ,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;IAClE,iDAAiD;IACjD,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"auth-card.d.ts","sourceRoot":"","sources":["../../src/components/auth-card.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAK1E,UAAU,sBAAuB,SAAQ,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;IAClE,iDAAiD;IACjD,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,2CAoM9D"}
|
|
@@ -124,10 +124,45 @@ export function AscendKitAuthCard(props) {
|
|
|
124
124
|
--ak-notif-info-border: rgba(59, 130, 246, 0.2);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
-
` })] })), _jsx(AuthView, { ...props, socialLayout: props.socialLayout ?? "vertical", classNames: {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
` })] })), _jsxs("div", { className: "ak-auth-view-wrapper", children: [_jsx(AuthView, { ...props, socialLayout: props.socialLayout ?? "vertical", classNames: {
|
|
128
|
+
content: "overflow-x-hidden",
|
|
129
|
+
continueWith: "w-full min-w-0",
|
|
130
|
+
separator: "min-w-0 flex-1",
|
|
131
|
+
...props.classNames,
|
|
132
|
+
} }), _jsx("style", { children: `
|
|
133
|
+
/*
|
|
134
|
+
* Fallback styles for Better Auth UI's Tailwind utility classes.
|
|
135
|
+
* These ensure correct rendering when the host app's Tailwind config
|
|
136
|
+
* does not scan node_modules/@daveyplate/better-auth-ui.
|
|
137
|
+
* Each rule uses .ak-auth-view-wrapper to avoid leaking into the host app.
|
|
138
|
+
*/
|
|
139
|
+
.ak-auth-view-wrapper .size-4 { width: 1rem; height: 1rem; }
|
|
140
|
+
.ak-auth-view-wrapper .size-5 { width: 1.25rem; height: 1.25rem; }
|
|
141
|
+
.ak-auth-view-wrapper .shrink-0,
|
|
142
|
+
.ak-auth-view-wrapper .flex-shrink-0 { flex-shrink: 0; }
|
|
143
|
+
.ak-auth-view-wrapper .w-full { width: 100%; }
|
|
144
|
+
.ak-auth-view-wrapper .flex { display: flex; }
|
|
145
|
+
.ak-auth-view-wrapper .grid { display: grid; }
|
|
146
|
+
.ak-auth-view-wrapper .items-center { align-items: center; }
|
|
147
|
+
.ak-auth-view-wrapper .justify-center { justify-content: center; }
|
|
148
|
+
.ak-auth-view-wrapper .gap-2 { gap: 0.5rem; }
|
|
149
|
+
.ak-auth-view-wrapper .gap-4 { gap: 1rem; }
|
|
150
|
+
.ak-auth-view-wrapper .gap-6 { gap: 1.5rem; }
|
|
151
|
+
.ak-auth-view-wrapper .flex-col { flex-direction: column; }
|
|
152
|
+
.ak-auth-view-wrapper .flex-row { flex-direction: row; }
|
|
153
|
+
.ak-auth-view-wrapper .flex-1 { flex: 1 1 0%; }
|
|
154
|
+
.ak-auth-view-wrapper .text-sm { font-size: 0.875rem; line-height: 1.25rem; }
|
|
155
|
+
.ak-auth-view-wrapper .text-xs { font-size: 0.75rem; line-height: 1rem; }
|
|
156
|
+
.ak-auth-view-wrapper .text-lg { font-size: 1.125rem; line-height: 1.75rem; }
|
|
157
|
+
.ak-auth-view-wrapper .font-semibold { font-weight: 600; }
|
|
158
|
+
.ak-auth-view-wrapper .rounded-md { border-radius: 0.375rem; }
|
|
159
|
+
.ak-auth-view-wrapper .rounded-lg { border-radius: 0.5rem; }
|
|
160
|
+
.ak-auth-view-wrapper .min-w-0 { min-width: 0; }
|
|
161
|
+
.ak-auth-view-wrapper .overflow-x-hidden { overflow-x: hidden; }
|
|
162
|
+
.ak-auth-view-wrapper .text-center { text-align: center; }
|
|
163
|
+
.ak-auth-view-wrapper .p-2 { padding: 0.5rem; }
|
|
164
|
+
.ak-auth-view-wrapper .p-4 { padding: 1rem; }
|
|
165
|
+
.ak-auth-view-wrapper .px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
|
|
166
|
+
.ak-auth-view-wrapper .h-9 { height: 2.25rem; }
|
|
167
|
+
` })] }), _jsx(BrandingBadge, {})] }));
|
|
133
168
|
}
|
package/dist/shared/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "0.3.
|
|
1
|
+
export declare const SDK_VERSION = "0.3.6";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/shared/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "0.3.
|
|
1
|
+
export const SDK_VERSION = "0.3.6";
|