Beta
The Neon Auth with Better Auth is in Beta. Share your feedback on Discord or via the Neon Console.
This guide shows you how to integrate Neon Auth into a Next.js (App Router) project using SDK methods directly. To use our pre-built UI components instead, see the UI components guide.
Enable Auth in your Neon project
Enable Auth in your Neon project and copy your Auth URL from Configuration.
Console path: Project → Branch → Auth → Configuration
Console
Install the Neon SDK
Install the Neon SDK into your Next.js app.
If you don't have a Next.js project
npx create-next-app@latest my-app --yes cd my-appTerminalnpm install @neondatabase/authSet up environment variables
Create a
.env.localfile in your project root and add your Auth URL:note
Replace the URL with your actual Auth URL from the Neon Console.
.env.localNEON_AUTH_BASE_URL=https://ep-xxx.neonauth.us-east-1.aws.neon.tech/neondb/authSet up your auth API routes
We need to mount the
authApiHandlerhandler to the auth API route. All Neon Auth APIs will be routed through this handler. Create a route file inside/api/auth/[...path]directory and add the following code:app/api/auth/[...path]/route.tsimport { authApiHandler } from '@neondatabase/auth/next/server'; export const { GET, POST } = authApiHandler();Add neonAuthMiddleware()
The
neonAuthMiddleware()ensures that user is authenticated before the request reaches your page components or API routes. Createproxy.tsfile in your project root:proxy.tsimport { neonAuthMiddleware } from "@neondatabase/auth/next/server"; export default neonAuthMiddleware({ // Redirects unauthenticated users to sign-in page loginUrl: "/auth/sign-in", }); export const config = { matcher: [ // Protected routes requiring authentication "/account/:path*", ], };note
Your Next.js project is now fully configured to use Neon Auth. Now, lets proceed with setting up the Auth UI Provider and wrap your layout with auth context.
Configure the auth clients
Client Components:
- The Auth UI components are client rendered and need access to the auth APIs. Lets first create the auth client in
lib/auth/client.tsfile then we pass it toNeonAuthUIProvider
Server Components:
- To use Auth APIs in server components and server actions, you can also create auth-server in
lib/auth/server.tsfile.
Copy and paste following code in
lib/auth/client.tsfile:'use client'; import { createAuthClient } from '@neondatabase/auth/next'; export const authClient = createAuthClient();- The Auth UI components are client rendered and need access to the auth APIs. Lets first create the auth client in
Create Sign up form
Lets create a sign-up form and action in
app/auth/sign-up/page.tsxandapp/auth/sign-up/actions.tsfiles respectively using the auth server instance we created in previous step- To create user with email and password, we will use
authServer.signUp.email()with user name, email address, and password - You can optionally add business logic before invoking the API, for example restrict signups to emails ending with
@my-company.com
Copy and paste following code in
app/auth/sign-up/actions.tsfile:'use server'; import { authServer } from '@/lib/auth/server'; import { redirect } from 'next/navigation'; export async function signUpWithEmail( _prevState: { error: string } | null, formData: FormData ) { const email = formData.get('email') as string; if (!email) { return { error: "Email address must be provided." } } // Optionally restrict sign ups based on email address // if (!email.trim().endsWith("@my-company.com")) { // return { error: 'Email must be from my-company.com' }; // } const { error } = await authServer.signUp.email({ email, name: formData.get('name') as string, password: formData.get('password') as string, }); if (error) { return { error: error.message || 'Failed to create account' }; } redirect('/'); }- To create user with email and password, we will use
Create Sign in form
Lets create a sign-in form and action in
app/auth/sign-in/page.tsxandapp/auth/sign-in/actions.tsfiles respectively.- To sign-in the user we will use
authServer.signIn.email()with user's email address and password.
Sign In'use server'; import { authServer } from '@/lib/auth/server'; import { redirect } from 'next/navigation'; export async function signInWithEmail( _prevState: { error: string } | null, formData: FormData ) { const { error } = await authServer.signIn.email({ email: formData.get('email') as string, password: formData.get('password') as string, }); if (error) { return { error: error.message || 'Failed to sign in. Try again' }; } redirect('/'); }- To sign-in the user we will use
Create home page
In last step, lets create the home page and display authenticated user status:
app/page.tsximport { authServer } from "@/lib/auth/server"; import Link from "next/link"; export default async function Home() { const { data } = await authServer.getSession(); if (data && data.user) { return ( <div className="flex flex-col gap-2 min-h-screen items-center justify-center bg-gray-900"> <h1 className="mb-4 text-4xl"> Logged in as <span className="font-bold underline">{data.user.name}</span> </h1> </div> ); } return ( <div className="flex flex-col gap-2 min-h-screen items-center justify-center bg-gray-900"> <h1 className="mb-4 text-4xl font-bold">Not logged in</h1> <div className="flex item-center gap-2"> <Link href='/auth/sign-up' className="inline-flex text-lg text-indigo-400 hover:underline"> Sign-up </Link> <Link href='/auth/sign-in' className="inline-flex text-lg text-indigo-400 hover:underline"> Sign-in </Link> </div> </div> ); }Start your app
Start the development server:
Open your browser to http://localhost:3000 and test sign-up and sign-in.
Safari users
Safari blocks third-party cookies on non-HTTPS connections. Use
npm run dev -- --experimental-httpsand openhttps://localhost:3000instead.Terminalnpm run dev
Available SDK methods
Both authClient and authServer expose similar API methods. If you would like to use auth APIs in client components, you can use authClient.
- authClient.signUp.email() - Create a new user account
- authClient.signIn.email() - Sign in with email and password
- authClient.signOut() - Sign out the current user
- authClient.getSession() - Get the current session
authServer.updateUser()- To update user details
Next steps
Need help?
Join our Discord Server to ask questions or see what others are doing with Neon. For paid plan support options, see Support.