Skip to content
TechPulse
Daily Tech News, Gadget Reviews & Developer Guides
Explore guides →
  • Home
  • Programming
  • Web Development
  • How-To
  • Reviews
  • Career
  • About TechPulse
  • Contact Us
Home › How-To › How to Implement Google OAuth 2.0 in Next.js 15 with NextAuth: Complete 2026 Tutorial
How-To

How to Implement Google OAuth 2.0 in Next.js 15 with NextAuth: Complete 2026 Tutorial

By MD Rafikul Islam Published June 29, 2026 5 min read How-To

OAuth 2.0 with Google is the fastest way to add authentication to a Next.js application — users sign in with their Google account, eliminating password management and reducing friction. In 2026, NextAuth v5 (Auth.js) provides the cleanest integration for Next.js 15 App Router. This tutorial covers the complete implementation.

Table of contents

  1. Prerequisites
  2. Step 1: Set Up Google OAuth Credentials
  3. Step 2: Install NextAuth v5
  4. Step 3: Configure Auth.js
  5. Step 4: Create Route Handler
  6. Step 5: Environment Variables
  7. Step 6: Add Sign-In/Out to UI
  8. Step 7: Access Session in Server Components
  9. Step 8: Protect Routes with Middleware
  10. Step 9: Database Integration (Optional but Recommended)
  11. Step 10: Access Session in Client Components
  12. Frequently Asked Questions
  13. Conclusion

Prerequisites

  • Next.js 15 project (App Router)
  • Google Cloud Console account (free)
  • PostgreSQL database (optional, for persisting sessions)

Step 1: Set Up Google OAuth Credentials

  1. Go to console.cloud.google.com
  2. Create a new project (or select existing)
  3. Navigate to APIs & Services → Credentials → Create Credentials → OAuth Client ID
  4. Application type: Web Application
  5. Authorized redirect URIs: http://localhost:3000/api/auth/callback/google
  6. Add production URI when deploying: https://yourdomain.com/api/auth/callback/google
  7. Save and copy your Client ID and Client Secret

Step 2: Install NextAuth v5

npm install next-auth@beta
# or
pnpm add next-auth@beta

Step 3: Configure Auth.js

Create auth.ts in your project root:

import NextAuth from "next-auth";
import Google from "next-auth/providers/google";

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    Google({
      clientId:     process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  callbacks: {
    async session({ session, token }) {
      // Add user ID to session
      if (token.sub) {
        session.user.id = token.sub;
      }
      return session;
    },
    async jwt({ token, account, profile }) {
      if (account) {
        token.accessToken = account.access_token;
      }
      return token;
    },
  },
  pages: {
    signIn: "/login",    // custom sign-in page
    error:  "/auth/error",
  },
});

Step 4: Create Route Handler

Create app/api/auth/[...nextauth]/route.ts:

import { handlers } from "@/auth";
export const { GET, POST } = handlers;

Step 5: Environment Variables

# .env.local
GOOGLE_CLIENT_ID=your_client_id_here
GOOGLE_CLIENT_SECRET=your_client_secret_here
AUTH_SECRET=generate_with_openssl_rand_base64_32

# Generate AUTH_SECRET:
# openssl rand -base64 32

Step 6: Add Sign-In/Out to UI

// components/AuthButtons.tsx
import { signIn, signOut } from "@/auth";

export function SignInButton() {
  return (
    <form action={async () => {
      "use server";
      await signIn("google");
    }}>
      <button type="submit">Sign in with Google</button>
    </form>
  );
}

export function SignOutButton() {
  return (
    <form action={async () => {
      "use server";
      await signOut({ redirectTo: "/" });
    }}>
      <button type="submit">Sign out</button>
    </form>
  );
}

Step 7: Access Session in Server Components

// app/dashboard/page.tsx
import { auth } from "@/auth";
import { redirect } from "next/navigation";

export default async function Dashboard() {
  const session = await auth();

  if (!session?.user) {
    redirect("/login");
  }

  return (
    <main>
      <h1>Welcome, {session.user.name}!</h1>
      <img src={session.user.image!} alt="avatar" width={40} height={40} />
      <p>Email: {session.user.email}</p>
    </main>
  );
}

Step 8: Protect Routes with Middleware

// middleware.ts
import { auth } from "@/auth";
import { NextResponse } from "next/server";

export default auth((req) => {
  const isLoggedIn = !!req.auth;
  const isProtected = req.nextUrl.pathname.startsWith("/dashboard");

  if (isProtected && !isLoggedIn) {
    const loginUrl = new URL("/login", req.url);
    loginUrl.searchParams.set("callbackUrl", req.nextUrl.href);
    return NextResponse.redirect(loginUrl);
  }
  return NextResponse.next();
});

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};

Step 9: Database Integration (Optional but Recommended)

npm install @auth/prisma-adapter @prisma/client prisma
// auth.ts with database adapter
import { PrismaAdapter } from "@auth/prisma-adapter";
import { db } from "@/lib/db";  // your Prisma client

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(db),
  session: { strategy: "database" },  // store sessions in DB
  providers: [Google(...)],
});

Database sessions allow invalidating sessions server-side (useful for banning users or forced sign-out) and persist login across server restarts — not possible with JWT-only sessions.

Step 10: Access Session in Client Components

// Wrap your app with SessionProvider in layout.tsx
// app/layout.tsx
import { SessionProvider } from "next-auth/react";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <SessionProvider>{children}</SessionProvider>
      </body>
    </html>
  );
}

// Client component using session
"use client";
import { useSession } from "next-auth/react";

export function UserAvatar() {
  const { data: session, status } = useSession();

  if (status === "loading") return <Skeleton />;
  if (!session) return <SignInButton />;

  return <img src={session.user.image!} alt={session.user.name!} />;
}

Frequently Asked Questions

Q: JWT vs Database sessions — which should I use?
A: JWT for simple apps where you don’t need server-side session invalidation. Database for apps where you need to revoke sessions, audit logins, or store user preferences tied to sessions.

Q: How do I add more OAuth providers?
A: Import and add to the providers array: import GitHub from "next-auth/providers/github". NextAuth supports 70+ providers with the same pattern.

Q: How do I restrict sign-in to specific email domains?
A: Use the signIn callback: async signIn({ user }) { return user.email?.endsWith("@company.com") ?? false; }

Q: Is Auth.js (NextAuth v5) production-ready?
A: As of 2026, yes — the beta has been stable for many months and is widely used in production. The API is stable and recommended for new projects.

Q: How do I access the Google access token for API calls?
A: Store it in the JWT callback (token.accessToken = account.access_token) and expose it in the session callback. Access via session.accessToken.

Conclusion

NextAuth v5 + Google OAuth gives you production-ready authentication in Next.js 15 with about 50 lines of code. The route handler pattern, server action sign-in/out, middleware protection, and optional database adapter cover every real-world authentication requirement. Add GitHub, Discord, or email/password alongside Google using the same pattern — NextAuth handles the complexity so you don’t have to.

Share this article

X / TwitterFacebookWhatsAppLinkedInTelegram

Continue reading

  • Should I Learn React or Vue.js in 2026? Honest Comparison for Beginners
  • Python functools Complete Guide 2026: lru_cache, partial and reduce
  • Machine Learning Interview Questions 2026: Algorithms, Metrics and Deep Learning
  • How Many Hours a Day Should I Code to Actually Get Good in 2026?
  • Cloud-Native Development Guide 2026: Kubernetes, GitOps and Observability
  • Python Generators and Iterators Guide 2026: yield, send and Pipelines
Tags:auth jsauthentication nextjsgoogle sign innextauth v5nextjs oauth 2026
MD Rafikul Islam

Written by

MD Rafikul Islam

MD Rafikul Islam is a software developer and editor of TechPulse. He writes about developer tools, hardware, AI, and practical technology decisions. Some articles are based on cited documentation and analysis rather than hands-on testing; readers should check each article for sources and testing disclosures. Corrections are welcome at rony.yf25@gmail.com.

✍️ Leave a Comment

Cancel reply

Your email address will not be published. Required fields are marked *

← Previous
Best Mechanical Keyboards for Developers 2026: Keychron Q6 vs Moonlander vs HHKB Review
Next →
Is Web3 and Blockchain Development Still Worth Learning in 2026?

FOLLOW TECHPULSE

New guides in your feed reader. Free to follow, with no email signup.

Open RSS feed →

LATEST GUIDES

1
Chrome DevTools Ads Panel: Find Ad Scripts and Page Costs September 29, 2026 · 5 min read
2
GitHub Actions Self-Hosted Runner Deadline: September 29 September 29, 2026 · 5 min read
3
GitHub Copilot Local Sandboxing: Setup, Defaults and Limits September 27, 2026 · 6 min read
4
npm Trusted Publishing: Stage GitHub Actions Releases Before They Go Live September 26, 2026 · 7 min read
5
Googlebook Australia: What to Check Before Spending A$2,299 September 25, 2026 · 8 min read

📂 CATEGORIES

Programming 222
How-To 164
Web Development 118
Reviews 59
Accessories 41
Career 36
AI & Machine Learning 14
Headphones 6

🏷 POPULAR TAGS

2026 JavaScript Python AI tags self taught developer Developer Salary git workflow access control allow origin cloud storage AI Coding Programming Productivity automation Web Development Code Quality

⚡ ABOUT TECHPULSE

⚡

Daily tech news, honest reviews, and practical guides for developers and tech enthusiasts.

Learn More →
TechPulse

Daily Tech News, Gadget Reviews & Developer Guides

CATEGORIES

  • Programming
  • How-To
  • Web Development
  • Reviews
  • Accessories
  • Career

QUICK LINKS

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service
  • Editorial Policy
  • Disclaimer
  • All Articles
  • RSS Feed
  • Sitemap
© 2026 TechPulse. All rights reserved. Built with TechPulse Theme