diff --git a/content/docs/auth/guides/manage-auth-api.md b/content/docs/auth/guides/manage-auth-api.md index bbde634041..821f3d7669 100644 --- a/content/docs/auth/guides/manage-auth-api.md +++ b/content/docs/auth/guides/manage-auth-api.md @@ -133,6 +133,7 @@ The Neon API also provides endpoints for managing auth configuration at the bran | `/email_and_password` | GET, PATCH | Configure email/password authentication | | `/users` | POST, DELETE, PUT | Create, delete, and manage user roles | | `/plugins` | GET, PATCH | View and configure [auth plugins](/docs/auth/guides/plugins) | +| `/plugins/magic-link` | PATCH | Configure the [Magic Link plugin](/docs/auth/guides/plugins/magic-link) | | `/webhooks` | GET, PUT | Configure webhook notifications | | `/allow_localhost` | GET, PATCH | Toggle localhost access for development | | `/send_test_email` | POST | Send a test email to verify email configuration | diff --git a/content/docs/auth/guides/plugins.md b/content/docs/auth/guides/plugins.md index 66bf2f9bab..4f6f2956bc 100644 --- a/content/docs/auth/guides/plugins.md +++ b/content/docs/auth/guides/plugins.md @@ -28,10 +28,11 @@ The following Better Auth plugins are currently supported in Neon Auth: | [Admin](/docs/auth/guides/plugins/admin) | ✅ Supported | | [Email OTP](/docs/auth/guides/plugins/email-otp) | ✅ Supported | | [JWT](/docs/auth/guides/plugins/jwt) | ✅ Supported | +| [Magic Link](/docs/auth/guides/plugins/magic-link) | ✅ Supported | | [Organization](/docs/auth/guides/plugins/organization) | ⚠️ Partial (JWT token claims under development) | | [Open API](/docs/auth/guides/plugins/openapi) | ✅ Supported | -For more runnable Neon Auth samples, see [Example applications](/docs/auth/overview#example-applications). The **Organization** plugin demo is **[neon-auth-orgs-example](https://github.com/neondatabase/neon-js/tree/main/examples/neon-auth-orgs-example)**; see the [Organization plugin](/docs/auth/guides/plugins/organization) page for context. +For more runnable Neon Auth samples, see [Example applications](/docs/auth/overview#example-applications). The **Organization** plugin demo is **[neon-auth-orgs-example](https://github.com/neondatabase/neon-js/tree/main/examples/neon-auth-orgs-example)** and the **Magic Link** demo is **[neon-auth-magic-link-example](https://github.com/neondatabase/neon-js/tree/main/examples/neon-auth-magic-link-example)**. For the latest status (including what’s coming next), see the [Neon Auth roadmap](/docs/auth/roadmap). diff --git a/content/docs/auth/guides/plugins/magic-link.md b/content/docs/auth/guides/plugins/magic-link.md new file mode 100644 index 0000000000..bb2f08a20f --- /dev/null +++ b/content/docs/auth/guides/plugins/magic-link.md @@ -0,0 +1,130 @@ +--- +title: Magic Link +subtitle: Passwordless sign-in via email magic links +summary: >- + Covers the setup of Magic Link functionality in Neon Auth, enabling users to + sign in by clicking a link sent to their email, with no password required. +enableTableOfContents: true +updatedOn: '2026-04-14T00:00:00.000Z' +--- + + + +Neon Auth is built on [Better Auth](https://www.better-auth.com/) and supports the [Magic Link](https://www.better-auth.com/docs/plugins/magic-link) plugin through the Neon SDK. You don't need to install or configure the Better Auth Magic Link plugin directly. + +Magic Link lets users sign in by clicking a link sent to their email. No password is required. The flow works like this: + +1. The user enters their email address. +2. Neon Auth sends an email containing a unique, time-limited link. +3. The user clicks the link, which verifies the token, creates a session, and redirects them to your app. + +## Prerequisites + +- A Neon project with **Auth enabled** +- The **Magic Link plugin enabled** (see [Enable Magic Link](#enable-magic-link) below) + +## Enable Magic Link + + + + + +1. Open the [Neon Console](https://console.neon.tech). +2. Select your project and go to **Auth** > **Plugins**. +3. Toggle **Magic Link** on. +4. Configure the options: + - **Link Expiration** (5-1440 minutes, default: 5) controls how long a magic link stays valid. + - **Allow New User Registration**, when disabled, restricts magic links to existing users only (sign-in only, no sign-up). + +![Neon Console Auth Plugins tab with Magic Link settings](/docs/auth/neon_auth_plugins_magic_link.png) + + + + + +Send a `PATCH` request to configure the Magic Link plugin. All request body fields are optional; send only the fields you want to change. + +```bash shouldWrap +curl -X PATCH \ + "https://console.neon.tech/api/v2/projects/{project_id}/branches/{branch_id}/auth/plugins/magic-link" \ + -H "Authorization: Bearer $NEON_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "enabled": true, + "expires_in": 5, + "disable_sign_up": false + }' +``` + +| Field | Type | Default | Description | +| ----------------- | ------- | ------- | ------------------------------------------------------- | +| `enabled` | boolean | `false` | Whether the Magic Link plugin is active | +| `expires_in` | integer | `5` | Minutes before the magic link expires (5-1440) | +| `disable_sign_up` | boolean | `false` | When `true`, magic links only work for existing users | + + + + + +## Use Magic Link with SDK methods + +Build a custom magic link flow using the [Neon SDK](/docs/reference/javascript-sdk). Call `signIn.magicLink()` with the user's email and a callback URL. Neon Auth sends the email and redirects the user to `callbackURL` after they click the link. + +```ts shouldWrap filename="src/send-magic-link.ts" +import { authClient } from '@/lib/auth/client'; + +export async function sendMagicLink(email: string) { + const { error } = await authClient.signIn.magicLink({ + email, + callbackURL: '/dashboard', + }); + + if (error) throw error; +} +``` + +After calling `signIn.magicLink()`, show the user a "check your email" message. For a complete working example with error handling, resend, and state management, see the [magic link example app](https://github.com/neondatabase/neon-js/tree/main/examples/neon-auth-magic-link-example) in the neon-js repository. + +## Use Magic Link with UI components + +If you're already using Neon Auth UI components, you can enable Magic Link with a single prop instead of building a custom form. Pass the `magicLink` prop to `NeonAuthUIProvider`: + +```tsx shouldWrap filename="app/layout.tsx" +'use client'; + +import { authClient } from '@/lib/auth/client'; +import { NeonAuthUIProvider } from '@neondatabase/neon-js/auth/react/ui'; +import '@neondatabase/neon-js/ui/css'; +import './globals.css'; + +export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) { + return ( + + + + {children} + + + + ); +} +``` + +Users can now sign in with a magic link by selecting the option on the sign-in screen and entering their email. + +> If you haven't set up Neon Auth UI components yet, see the [UI components reference](/docs/auth/reference/ui-components) for setup, or the [Next.js](/docs/auth/quick-start/nextjs-api-only) or [React](/docs/auth/quick-start/react) quick start for building custom forms instead. + +## Webhooks + +When a magic link needs to be delivered, Neon Auth fires the `send.magic_link` webhook event with `link_type: "sign-in"`. If you subscribe to this event, Neon Auth skips its built-in email and your webhook handler is responsible for delivering the link (for example, via a custom email template or SMS). + +See the [Webhooks guide](/docs/auth/guides/webhooks) for configuration details and payload format. + +## Email provider configuration + +For production environments, we strongly recommend using a dedicated email provider. The default shared SMTP should be used only during development. See the [Email provider configuration guide](/docs/auth/production-checklist#email-provider) for setup instructions. + + diff --git a/content/docs/auth/guides/webhooks.md b/content/docs/auth/guides/webhooks.md index db0e5bb844..114799ad45 100644 --- a/content/docs/auth/guides/webhooks.md +++ b/content/docs/auth/guides/webhooks.md @@ -144,14 +144,14 @@ The `user` object fields are all optional and vary by event. Available fields: ` | Field | Type | Description | | ------------ | ------------ | --------------------------------------------- | -| `link_type` | string | `"email-verification"` or `"forget-password"` | +| `link_type` | string | `"sign-in"`, `"email-verification"`, or `"forget-password"` | | `link_url` | string | Full verification URL with embedded token | | `token` | string | Raw token for building custom redirect URLs | | `expires_at` | ISO datetime | Expiry time | | `ip_address` | string | Requester's IP address | | `user_agent` | string | Requester's user agent | -Magic links do not include a `delivery_preference` field. Your webhook handler determines the delivery channel. +The `"sign-in"` link type is sent when a user signs in via the [Magic Link plugin](/docs/auth/guides/plugins/magic-link). Magic links do not include a `delivery_preference` field. Your webhook handler determines the delivery channel. ### `user.before_create` and `user.created` event data diff --git a/content/docs/auth/overview.md b/content/docs/auth/overview.md index 035111ddf1..1e4b7e69b4 100644 --- a/content/docs/auth/overview.md +++ b/content/docs/auth/overview.md @@ -151,7 +151,7 @@ See [Branching authentication](/docs/auth/branching-authentication) for details ## Example applications -Beyond the quick starts on this site, the [neondatabase/neon-js](https://github.com/neondatabase/neon-js) monorepo ships **more runnable Neon Auth and `neon-js` samples** under [`examples/`](https://github.com/neondatabase/neon-js/tree/main/examples). It includes Next.js and React apps, cross-subdomain setups, the Organization plugin, alternative UI stacks, and Data API patterns. Each folder includes its own README (many workflows use **bun** from the repository root). Browse there when you want a full project to clone next to the guides here. +Beyond the quick starts on this site, the [neondatabase/neon-js](https://github.com/neondatabase/neon-js) monorepo ships **more runnable Neon Auth and `neon-js` samples** under [`examples/`](https://github.com/neondatabase/neon-js/tree/main/examples), including the [Organization plugin](https://github.com/neondatabase/neon-js/tree/main/examples/neon-auth-orgs-example) and [Magic Link](https://github.com/neondatabase/neon-js/tree/main/examples/neon-auth-magic-link-example) demos, Next.js and React apps, cross-subdomain setups, alternative UI stacks, and Data API patterns. Each folder includes its own README (many workflows use **bun** from the repository root). Browse there when you want a full project to clone next to the guides here. ## Availability diff --git a/content/docs/auth/reference/ui-components.md b/content/docs/auth/reference/ui-components.md index b35914fb9c..ae875b7404 100644 --- a/content/docs/auth/reference/ui-components.md +++ b/content/docs/auth/reference/ui-components.md @@ -49,6 +49,7 @@ function App() { | `avatar` | `AvatarOptions` | Avatar upload and display configuration | `avatar={{ size: 256, extension: 'webp' }}` | | `additionalFields` | `AdditionalFields` | Custom fields for sign-up and account settings | See example below | | `credentials.forgotPassword` | `boolean` | Enable forgot password flow | `credentials={{ forgotPassword: true }}` | +| `magicLink` | `boolean` | Enable passwordless magic link sign-in option | `magicLink` | ### Enable OAuth Providers @@ -206,6 +207,35 @@ function App() { } ``` +### Next.js App Router + +Create a route file at `app/auth/[path]/page.tsx` to render `AuthView` for sign-in, sign-up, and other auth views: + +```tsx +import { AuthView } from '@neondatabase/neon-js/auth/react/ui'; +import { authViewPaths } from '@neondatabase/neon-js/auth/react/ui/server'; + +export const dynamicParams = false; + +export function generateStaticParams() { + return Object.values(authViewPaths).map((path) => ({ path })); +} + +export default async function AuthPage({ + params, +}: { + params: Promise<{ path: string }>; +}) { + const { path } = await params; + + return ( +
+ +
+ ); +} +``` + ### User Menu ```tsx diff --git a/content/docs/auth/roadmap.md b/content/docs/auth/roadmap.md index 5472ea624f..8ea1aff799 100644 --- a/content/docs/auth/roadmap.md +++ b/content/docs/auth/roadmap.md @@ -55,6 +55,7 @@ Neon Auth is built on [Better Auth](https://www.better-auth.com/). Not all Bette | [Admin](/docs/auth/guides/plugins/admin) | ✅ Supported | | [Organization](/docs/auth/guides/plugins/organization) | ⚠️ Partial (JWT token claims under development) | | [JWT](/docs/auth/guides/plugins/jwt) | ✅ Supported | +| [Magic Link](/docs/auth/guides/plugins/magic-link) | ✅ Supported | | [Open API](/docs/auth/guides/plugins/openapi) | ✅ Supported | See [Set up OAuth](/docs/auth/guides/setup-oauth) for Neon-specific OAuth configuration (including Vercel). Email flows such as verification and password reset are covered in [Email verification](/docs/auth/guides/email-verification), [Password reset](/docs/auth/guides/password-reset), and [User management](/docs/auth/guides/user-management). @@ -75,7 +76,6 @@ Branch-aware auth (separate auth state per Neon branch) is supported; see [Branc | Plugin | Status | | ----------------------------------------------------------------- | --------------- | -| [Magic link](https://www.better-auth.com/docs/plugins/magic-link) | 🔜 Coming soon | | Phone number (bring your own SMS provider) | 🔜 Coming soon | | MFA support | 🔜 Coming soon | | [Admin](/docs/auth/guides/plugins/admin) plugin customization | 🔜 Coming soon | diff --git a/content/docs/navigation.yaml b/content/docs/navigation.yaml index 5cf1511a9e..d051538c15 100644 --- a/content/docs/navigation.yaml +++ b/content/docs/navigation.yaml @@ -482,6 +482,8 @@ slug: auth/guides/plugins/email-otp - title: JWT slug: auth/guides/plugins/jwt + - title: Magic Link + slug: auth/guides/plugins/magic-link - title: OpenAPI slug: auth/guides/plugins/openapi - title: Organization diff --git a/public/docs/auth/neon_auth_plugins_magic_link.png b/public/docs/auth/neon_auth_plugins_magic_link.png new file mode 100644 index 0000000000..74a963732c Binary files /dev/null and b/public/docs/auth/neon_auth_plugins_magic_link.png differ