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
최근 소스 활동
2026년 1월 29일 12:32
감지된 SKILL.md 언어
영어
스타
16
포크
15

설치 방법

기본적으로 소스를 먼저 확인하는 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에서 보기