Skip to main content

neon-auth-nextjs

Sets up Neon Auth in Next.js App Router applications. Configures API routes, middleware, server components, and UI. Use when adding auth-only to Next.js apps (no database needed).

الانتقال إلى التثبيت

معلومات المصدر

المستودع
neondatabase/neon-js
آخر نشاط في المصدر
٢٩ يناير ٢٠٢٦ في ١٢:٣٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٦
التفرعات
١٥

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
neon-auth-nextjs
description
Sets up Neon Auth in Next.js App Router applications. Configures API routes, middleware, server components, and UI. Use when adding auth-only to Next.js apps (no database needed).
allowed-tools
["Bash","Write","Read","Edit","Glob","Grep"]
# Neon Auth for Next.js Help developers set up @neondatabase/auth in Next.js App Router applications (auth only, no database). ## When to Use Use this skill when: - Setting up Neon Auth in Next.js (App Router) - User mentions "next.js", "next", or "app router" with Neon Auth - Auth-only setup (no database needed) ## Critical Rules 1. **Server vs Client imports**: Use correct import paths 2. **`'use client'` directive**: Required for client components using hooks 3. **CSS Import**: Choose ONE - either `/ui/css` OR `/ui/tailwind`, never both 4. **onSessionChange**: Always call `router.refresh()` to update Server Components ## Critical Imports | Purpose | Import From | |---------|-------------| | Unified Server (`createNeonAuth`) | `@neondatabase/auth/next/server` | | Client Auth | `@neondatabase/auth/next` | | UI Components | `@neondatabase/auth/react/ui` | | View Paths (static params) | `@neondatabase/auth/react/ui/server` | **Note**: Use `createNeonAuth()` from `@neondatabase/auth/next/server` to get a unified `auth` instance that provides: - `.handler()` - API route handler - `.middleware()` - Route protection middleware - All Better Auth server methods (`.signIn`, `.signUp`, `.getSession`, etc.) --- ## Setup ### 1. Install ```bash npm install @neondatabase/auth ``` ### 2. Environment (`.env.local`) ``` NEON_AUTH_BASE_URL=https://your-auth.neon.tech NEON_AUTH_COOKIE_SECRET=your-secret-at-least-32-characters-long ``` **Important**: Generate a secure secret (32+ characters) for production: ```bash openssl rand -base64 32 ``` ### 3. Server Setup (`lib/auth/server.ts`) Create a auth instance that provides handler, middleware, and server methods: ```typescript import { createNeonAuth } from '@neondatabase/auth/next/server'; export const auth = createNeonAuth({ baseUrl: process.env.NEON_AUTH_BASE_URL!, cookies: { secret: process.env.NEON_AUTH_COOKIE_SECRET!, sessionDataTtl: 300, // Optional: session data cache TTL in seconds (default: 300 = 5 min) domain: '.example.com', // Optional: for cross-subdomain cookies }, }); ``` ### 4. API Route (`app/api/auth/[...path]/route.ts`) ```typescript import { auth } from '@/lib/auth/server'; export const { GET, POST } = auth.handler(); ``` ### 5. Middleware (`middleware.ts`) ```typescript import { auth } from '@/lib/auth/server'; export default auth.middleware({ loginUrl: '/auth/sign-in', }); export const config = { matcher: ['/dashboard/:path*', '/account/:path*'], }; ``` ### 6. Client (`lib/auth/client.ts`) ```typescript 'use client'; import { createAuthClient } from '@neondatabase/auth/next'; export const authClient = createAuthClient(); ``` ### 7. Provider (`app/providers.tsx`) ```typescript 'use client'; import { NeonAuthUIProvider } from '@neondatabase/auth/react/ui'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { authClient } from '@/lib/auth/client'; export function Providers({ children }: { children: React.ReactNode }) { const router = useRouter(); return ( <NeonAuthUIProvider authClient={authClient} navigate={router.push} replace={router.replace} onSessionChange={() => router.refresh()} redirectTo="/dashboard" Link={({href, children}) => <Link to={href}>{children}</Link>} > {children} </NeonAuthUIProvider> ); } ``` ### 8. Layout (`app/layout.tsx`) ```typescript import { Providers } from './providers'; import '@neondatabase/auth/ui/css'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <Providers>{children}</Providers> </body> </html> ); } ``` ### 9. Auth Pages (`app/auth/[path]/page.tsx`) ```typescript import { AuthView } from '@neondatabase/auth/react/ui'; import { authViewPaths } from '@neondatabase/auth/react/ui/server'; 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 <AuthView pathname={path} />; } ``` --- ## CSS & Styling ### Import Options **Without Tailwind** (pre-built CSS bundle ~47KB): ```typescript // app/layout.tsx import '@neondatabase/auth/ui/css'; ``` **With Tailwind CSS v4** (`app/globals.css`): ```css @import 'tailwindcss'; @import '@neondatabase/auth/ui/tailwind'; ``` **IMPORTANT**: Never import both - causes duplicate styles. ### Dark Mode The provider includes `next-themes`. Control via `defaultTheme` prop: ```typescript <NeonAuthUIProvider defaultTheme="system" // 'light' | 'dark' | 'system' // ... > ``` ### Custom Theming Override CSS variables in `globals.css`: ```css :root { --primary: hsl(221.2 83.2% 53.3%); --primary-foreground: hsl(210 40% 98%); --background: hsl(0 0% 100%); --foreground: hsl(222.2 84% 4.9%); --card: hsl(0 0% 100%); --card-foreground: hsl(222.2 84% 4.9%); --border: hsl(214.3 31.8% 91.4%); --input: hsl(214.3 31.8% 91.4%); --ring: hsl(221.2 83.2% 53.3%); --radius: 0.5rem; } .dark { --background: hsl(222.2 84% 4.9%); --foreground: hsl(210 40% 98%); /* ... dark mode overrides */ } ``` --- ## NeonAuthUIProvider Props Full configuration options: ```typescript <NeonAuthUIProvider // Required authClient={authClient} // Navigation (Next.js specific) navigate={router.push} // router.push for navigation replace={router.replace} // router.replace for redirects onSessionChange={() => router.refresh()} // Refresh Server Components! redirectTo="/dashboard" // Where to redirect after auth Link={({href, children}) => <Link to={href}>{children}</Link>} // Next.js Link component // Social/OAuth Providers social={{ providers: ['google'], }} // Feature Flags emailOTP={true} // Enable email OTP sign-in emailVerification={true} // Require email verification magicLink={false} // Magic link (disabled by default) multiSession={false} // Multiple sessions (disabled) // Credentials Configuration credentials={{ forgotPassword: true, // Show forgot password link }} // Sign Up Fields signUp={{ fields: ['name'], // Additional fields: 'name', 'username', etc. }} // Account Settings Fields account={{ fields: ['image', 'name', 'company', 'age', 'newsletter'], }} // Organization Features organization={{}} // Enable org features // Dark Mode defaultTheme="system" // 'light' | 'dark' | 'system' // Custom Labels localization={{ SIGN_IN: 'Welcome Back', SIGN_UP: 'Create Account', FORGOT_PASSWORD: 'Forgot Password?', OR_CONTINUE_WITH: 'or continue with', }} > {children} </NeonAuthUIProvider> ``` --- ## Server Components (RSC) ### Get Session in Server Component ```typescript // NO 'use client' - this is a Server Component import { auth } from '@/lib/auth/server'; // Server components using `auth` methods must be rendered dynamically export const dynamic = 'force-dynamic' export async function Profile() { const { data: session } = await auth.getSession(); if (!session?.user) return <div>Not signed in</div>; return ( <div> <p>Hello, {session.user.name}</p> <p>Email: {session.user.email}</p> </div> ); } ``` ### Route Handler with Auth ```typescript // app/api/user/route.ts import { auth } from '@/lib/auth/server'; import { NextResponse } from 'next/server'; export async function GET() { const { data: session } = await auth.getSession(); if (!session?.user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } return NextResponse.json({ user: session.user }); } ``` --- ## Server Actions Server actions use the same `auth` instance from `lib/auth/server.ts`: ### Sign In Action ```typescript // app/actions/auth.ts 'use server'; import { auth } from '@/lib/auth/server'; import { redirect } from 'next/navigation'; export async function signIn(formData: FormData) { const { error } = await auth.signIn.email({ email: formData.get('email') as string, password: formData.get('password') as string, }); if (error) { return { error: error.message }; } redirect('/dashboard'); } export async function signUp(formData: FormData) { const { error } = await auth.signUp.email({ email: formData.get('email') as string, password: formData.get('password') as string, name: formData.get('name') as string, }); if (error) { return { error: error.message }; } redirect('/dashboard'); } export async function signOut() { await auth.signOut(); redirect('/'); } ``` ### Available Server Methods The `auth` instance from `createNeonAuth()` provides all Better Auth server methods: ```typescript // Authentication auth.signIn.email({ email, password }) auth.signUp.email({ email, password, name }) auth.signOut() auth.getSession() // User Management auth.updateUser({ name, image }) // Organizations auth.organization.create({ name, slug }) auth.organization.list() // Admin (if enabled) auth.admin.listUsers() auth.admin.banUser({ userId }) ``` --- ## Client Components
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub