{"post":{"id":"82","slug":"nextjs-auth-supabase-nextauth-part-1","title":"Next.js Authentication with Supabase and NextAuth.js: A Deep Dive (Part 1 of 3)","excerpt":"Kick off your auth journey with Next.js, Supabase, and NextAuth.js. Part 1 covers project setup, environment variables, the Supabase client, and a minimal NextAuth CredentialsProvider config — the perfect foundation before we wire everything up in Part 2.","content":"\r\n# Next.js Authentication with Supabase and NextAuth.js: A Deep Dive (Part 1 of 3)\r\n\r\n> **By Sidharrth Mahadevan** | Published: February 22, 2025\r\n> [Original Article on Medium](https://medium.com/@sidharrthnix/next-js-authentication-with-supabase-and-nextauth-js-part-1-of-3-76dc97d3a345)\r\n\r\n---\r\n\r\n## Introduction\r\n\r\nWelcome to the first installment of our three-part series on **Next.js authentication** using **Supabase** and **NextAuth.js**. Here, we'll set up the foundation for a robust, modern authentication system — covering **sign-up, sign-in**, and eventually **password resets** in later posts. If you're tired of rolling your own auth from scratch, this combo provides a clean, hassle-free starting point.\r\n\r\n---\r\n\r\n## Series Overview\r\n\r\n- **Part 1**: Basic setup, minimal NextAuth config, and project structure *(You are here! 👈)*\r\n- **Part 2**: Full sign-in/sign-up implementation, session management, and protecting routes\r\n- **Part 3**: Advanced features (password reset, profile updates) and extra security tips\r\n\r\n---\r\n\r\n## 🤔 Why NextAuth & Supabase?\r\n\r\n- **NextAuth.js**: Zero-configuration authentication for Next.js, with built-in session management and support for custom credentials or OAuth providers.\r\n- **Supabase**: An open-source Firebase alternative offering a PostgreSQL database, real-time features, and easy-to-use auth APIs.\r\n\r\n**Bottom Line**: This combo gives you **production-grade** auth in a fraction of the time you'd spend rolling your own.\r\n\r\n---\r\n\r\n## 1. 🏗️ Project Setup\r\n\r\n### 1.1 Install NextAuth (Core Auth Library)\r\n\r\n```bash\r\nnpm install next-auth\r\n```\r\n\r\n### 1.2 Install the Supabase Client\r\n\r\n```bash\r\nnpm install @supabase/supabase-js\r\n```\r\n\r\n### 1.3 (Optional) Type Definitions\r\n\r\n```bash\r\nnpm install --save-dev @types/node @types/react\r\n```\r\n\r\n---\r\n\r\n## 1.4 Where to Place the NextAuth Route File\r\n\r\n### (a) Next.js 13+ App Router\r\n\r\nCreate `app/api/auth/[...nextauth]/route.ts`. This route acts as your **dynamic API route** — NextAuth automatically handles GET and POST requests to `/api/auth/[...nextauth]`.\r\n\r\n```\r\napp/\r\n├── api/\r\n│   └── auth/\r\n│       └── [...nextauth]/\r\n│           └── route.ts\r\n├── auth/\r\n│   ├── error/\r\n│   │   └── page.tsx\r\n│   └── signin/\r\n│       └── page.tsx\r\n└── ...\r\n```\r\n\r\n**Why `[...nextauth]`?** The catch-all route captures all of NextAuth's internal sub-routes (`callback`, `signin`, `signout`, etc.) in one place, keeping your auth logic tidy and centralized.\r\n\r\n### (b) Next.js 12 or Earlier (Pages Router)\r\n\r\nPlace the file at `pages/api/auth/[...nextauth].ts`:\r\n\r\n```\r\npages/\r\n├── api/\r\n│   └── auth/\r\n│       └── [...nextauth].ts\r\n├── auth/\r\n│   ├── signin.tsx\r\n│   └── error.tsx\r\n└── ...\r\n```\r\n\r\n---\r\n\r\n## 1.5 Create a Supabase Project\r\n\r\n1. Go to [supabase.com](https://supabase.com/) and sign up (the **Free Tier** covers most small-scale or learning needs).\r\n2. Create a new project from the dashboard.\r\n3. Note your **Project URL** and **Anon/Public API Key** — you'll need these for environment variables.\r\n\r\n---\r\n\r\n## 1.6 Environment Variables\r\n\r\nIn your project root, create a `.env` file:\r\n\r\n```env\r\nNEXTAUTH_URL=http://localhost:3000\r\nNEXTAUTH_SECRET=super_secret_value\r\nNEXT_PUBLIC_SUPABASE_URL=your_supabase_url\r\nNEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key\r\n```\r\n\r\n- `NEXTAUTH_URL`: The base URL for your Next.js app.\r\n- `NEXTAUTH_SECRET`: A random string used for signing tokens.\r\n- `NEXT_PUBLIC_SUPABASE_URL`: Your unique Supabase project URL.\r\n- `NEXT_PUBLIC_SUPABASE_ANON_KEY`: The anon key with limited privileges.\r\n\r\n> 💡 **Tip from Experience**: Setting up environment variables early saves debugging headaches later. I once spent hours troubleshooting auth issues only to realize my `NEXTAUTH_URL` had a typo! 🤦‍♂️\r\n\r\n---\r\n\r\n## 2. Building the Foundation\r\n\r\n### 2.1 🔑 Supabase Client\r\n\r\nCreate a reusable Supabase client (e.g. `lib/supabase.ts`):\r\n\r\n```ts\r\nimport { createClient } from '@supabase/supabase-js';\r\n\r\nexport const supabase = createClient(\r\n  process.env.NEXT_PUBLIC_SUPABASE_URL!,\r\n  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\r\n);\r\n```\r\n\r\n**Explanation:**\r\n- `createClient` initializes Supabase with your project's URL and anon key.\r\n- Non-null assertions (`!`) tell TypeScript these variables are always defined.\r\n- `NEXT_PUBLIC_` prefixes expose them to the browser so your client code can talk to Supabase directly.\r\n\r\n---\r\n\r\n### 2.2 🎯 Minimal NextAuth Configuration\r\n\r\nFor Next.js 13+ (App Router), create `app/api/auth/[...nextauth]/route.ts`:\r\n\r\n```ts\r\nimport NextAuth, { NextAuthOptions } from 'next-auth';\r\nimport CredentialsProvider from 'next-auth/providers/credentials';\r\n\r\nexport const authOptions: NextAuthOptions = {\r\n  providers: [\r\n    CredentialsProvider({\r\n      credentials: {\r\n        email:    { label: \"Email\",    type: \"email\"    },\r\n        password: { label: \"Password\", type: \"password\" },\r\n        mode:     { label: \"Mode\",     type: \"text\"     }\r\n      },\r\n      async authorize(credentials) {\r\n        // We'll implement this fully in Part 2\r\n        return null;\r\n      }\r\n    })\r\n  ],\r\n  session: {\r\n    strategy: 'jwt',\r\n  },\r\n  pages: {\r\n    signIn: '/auth/signin',\r\n    error:  '/auth/error'\r\n  },\r\n  secret: process.env.NEXTAUTH_SECRET\r\n};\r\n\r\nconst handler = NextAuth(authOptions);\r\nexport { handler as GET, handler as POST };\r\n```\r\n\r\n**Key Points:**\r\n- **CredentialsProvider**: Allows custom email/password logic. Returns `null` for now — no real sign-in yet.\r\n- **`session.strategy: 'jwt'`**: Uses JWT for minimal server overhead.\r\n- **`pages`**: Points NextAuth to your custom sign-in and error pages instead of the defaults.\r\n- **`secret`**: Ensures tokens are securely signed and verified.\r\n\r\n---\r\n\r\n## 🔜 What's Next?\r\n\r\nYou now have the **bare minimum** to integrate NextAuth.js into a Next.js project, plus a working Supabase client. In **Part 2**, we'll:\r\n\r\n- **Implement the sign-in/sign-up flows** (finally hooking up Supabase).\r\n- **Manage sessions** properly (including sign-out).\r\n- **Add real error handling** to surface helpful messages when credentials are wrong.\r\n\r\n---\r\n\r\n## 😊 Conclusion\r\n\r\nWe've **laid the groundwork** for a Next.js + NextAuth.js + Supabase authentication flow:\r\n\r\n- **Project & Env Setup**: NextAuth and Supabase environment variables are in place.\r\n- **Minimal NextAuth Config**: A `CredentialsProvider` stub ready for real logic in Part 2.\r\n- **Supabase Client**: A single file to connect to your Supabase instance.\r\n\r\nThanks for reading! Drop a comment with any questions — and stay tuned for Part 2, where the real magic happens! 😉\r\n\r\n---\r\n\r\n## Optional Resources\r\n\r\n- [NextAuth.js Official Docs](https://next-auth.js.org/getting-started/introduction)\r\n- [Supabase Docs](https://supabase.com/docs/guides/auth/server-side/nextjs)\r\n  ","category":"Tutorial","author":"Sidharrth Mahadevan","published_at":"2025-02-22T00:00:00.000Z","read_time":"4 min read","image_url":"https://miro.medium.com/v2/resize:fit:1100/format:webp/1*zftpVX_BGy0txJIT9JIgTw.png","tags":["Next.js","Authentication","Supabase","NextAuth","JavaScript"],"featured":true,"created_at":"2026-04-01T07:08:56.144Z","image_attribution":"Generated by AI-Hub"}}