Neon powers agents and codegen platforms across the board - including Atoms, a multi-agent AI team built for production
/Neon Auth/Next.js/API methods

Use Neon Auth with Next.js (API methods)

Build your own auth UI using SDK methods

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.

  1. 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

    Neon Auth Base URL

  2. 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-app
    Terminal
    npm install @neondatabase/auth
  3. Set up environment variables

    Create a .env.local file in your project root and add your Auth URL:

    note

    Replace the URL with your actual Auth URL from the Neon Console.

    .env.local
    NEON_AUTH_BASE_URL=https://ep-xxx.neonauth.us-east-1.aws.neon.tech/neondb/auth
  4. Set up your auth API routes

    We need to mount the authApiHandler handler 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.ts
    import { authApiHandler } from '@neondatabase/auth/next/server';
    
    export const { GET, POST } = authApiHandler();
  5. Add neonAuthMiddleware()

    The neonAuthMiddleware() ensures that user is authenticated before the request reaches your page components or API routes. Create proxy.ts file in your project root:

    proxy.ts
    import { 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.

  6. 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.ts file then we pass it to NeonAuthUIProvider

    Server Components:

    • To use Auth APIs in server components and server actions, you can also create auth-server in lib/auth/server.ts file.

    Copy and paste following code in lib/auth/client.ts file:

    'use client';
    
    import { createAuthClient } from '@neondatabase/auth/next';
    
    export const authClient = createAuthClient();
  7. Create Sign up form

    Lets create a sign-up form and action in app/auth/sign-up/page.tsx and app/auth/sign-up/actions.ts files 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.ts file:

    '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('/');
    }
  8. Create Sign in form

    Lets create a sign-in form and action in app/auth/sign-in/page.tsx and app/auth/sign-in/actions.ts files 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('/');
    }
  9. Create home page

    In last step, lets create the home page and display authenticated user status:

    app/page.tsx
    import { 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>
      );
    }
  10. 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-https and open https://localhost:3000 instead.

    Terminal
    npm 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.

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.

Last updated on

Was this page helpful?