meocuteequas
How to Add Google One Tap Sign-In to Your Next.js App

How to Add Google One Tap Sign-In to Your Next.js App

meocuteequas Feb 16, 2025

Ever wanted to make signing into your Next.js app as smooth as butter? Google One Tap is your answer! It lets users sign in with just a single click using their Google account. In this tutorial, I'll show you how to implement both Google One Tap and traditional Google Sign-In in your Next.js application using Auth.js (formerly NextAuth.js).

What We'll Build

By the end of this tutorial, your app will have:

  • A sleek Google One Tap popup that appears automatically
  • A traditional "Sign in with Google" button
  • Proper session handling and user authentication

Getting Your Tools Ready

Before we dive in, make sure you have:

  1. A Next.js project up and running
  2. Auth.js installed (npm install next-auth@beta)
  3. A Google Cloud Console project with OAuth credentials set up

Don't have these ready? No worries! Here's a quick guide to setting up Google OAuth credentials.

Let's Get Started!

1. Setting Up Auth.js Configuration

First, let's create our auth configuration. Create a new file called auth.config.ts in your app folder:

import type { NextAuthConfig } from "next-auth"; import GoogleProvider from "next-auth/providers/google"; export const authConfig: NextAuthConfig = { providers: [ Google, CredentialsProvider({ id: "googleonetap", name: "google-one-tap", credentials: { credential: { type: "text" }, }, async authorize(credentials) { const token = credentials.credential; const data = await fetchUserData(...); if (!data) return null; const { data: user } = data; const decoded = decodeAccessToken(user.access_token); return { ...decoded, ...user }; }, }) ] };

We're setting up two ways to sign in here:

  1. Traditional Google Sign-In
  2. Google One Tap (using our custom googleonetap provider)

2. Setting Up the Auth Provider

Next, we need to wrap our app with an auth provider. Create a new file for this app/context/auth-provider.tsx:

"use client"; import { SessionProvider } from "next-auth/react"; export default function AuthProvider({ children }: { children: React.ReactNode }) { return <SessionProvider>{children}</SessionProvider>; }

Now, let's set up our main auth configuration app/auth.ts:

export const { auth, handlers, signIn, signOut } = NextAuth({ ...authConfig, pages: { signIn: "/sign-in" }, callbacks: { async jwt({ token, user, account }) { if (user) { switch (account?.provider) { case "google": { const credential = account.id_token; const data = await fetchUserData(...); if (!data) return null; const { data: googleAccount } = data; const decoded = decodeAccessToken(googleAccount.access_token); token.access_token = googleAccount.access_token; token.refresh_token = googleAccount.refresh_token; break; } default: { token.access_token = user.access_token; token.refresh_token = user.refresh_token; } } } return token; }, async session({ session, token }) { return token ? { ...session, ...token } : session; }, }, });

And create the auth API route app/api/auth/[...nextauth]/route.ts:

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

3. Creating the Google One Tap Component

Here's where the magic happens! Let's create a component that handles the Google One Tap popup components/GoogleOneTap.tsx:

"use client"; // Add type definition for Google One Tap declare global { interface Window { google: { accounts: { id: { initialize: (config: any) => void; prompt: (callback: (notification: any) => void) => void; cancel: () => void; revoke: (hint: string, callback: () => void) => void; }; }; }; } } export default function GoogleOneTap() { const searchParams = useSearchParams(); const { data: session } = useSession(); const [isGoogleScriptLoaded, setIsGoogleScriptLoaded] = useState(false); const handleCredentialResponse = useCallback( (response: any) => { signIn("googleonetap", { credential: response.credential, redirect: false, }) .then(() => { const redirectUrl = searchParams.get("callbackUrl") || "/"; window.location.href = redirectUrl; }) .catch((error) => { console.error("Error signing in:", error); }); }, [searchParams] ); // ... rest of the component implementation }

4. Adding It All Together

Now, let's add our Google One Tap component to the main layout app/layout.tsx:

import AuthProvider from "@/context/auth-provider"; import GoogleOneTap from "@/components/GoogleOneTap"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <AuthProvider> {children} <GoogleOneTap /> </AuthProvider> </body> </html> ); }

5. Creating the Sign-In Page

Let's create a simple sign-in page with a Google button app/sign-in/page.tsx:

import { signIn } from "next-auth/react"; export default function SignIn() { return ( <div> <button onClick={() => signIn("google")} className="px-4 py-2 bg-blue-500 text-white rounded-md" > Sign in with Google </button> </div> ); }

6. Final Touch: Environment Variables

Create a .env.local file in your project root /.env.local:

NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-google-client-id NEXT_PUBLIC_GOOGLE_CLIENT_SECRET=your-google-client-secret

Remember to replace these with your actual Google OAuth credentials!

Testing It Out

Once you've got everything set up:

  1. Start your development server (npm run dev)
  2. Visit your site
  3. You should see the Google One Tap popup appear automatically
  4. Try clicking the "Sign in with Google" button on your sign-in page

Troubleshooting Tips

If you're not seeing the One Tap popup:

  • Make sure your Google OAuth credentials are correct
  • Check that you're using a real domain (One Tap doesn't work on localhost)
  • Ensure you've enabled the Google People API in your Google Cloud Console

What's Next?

Now that you've got Google One Tap working, you might want to:

  • Add loading states to your sign-in buttons
  • Customize the One Tap popup appearance
  • Add error handling for failed sign-in attempts

Conclusion

And there you have it! You've just added a super smooth sign-in experience to your Next.js app. Your users can now sign in with either Google One Tap or the traditional Google Sign-In button. Pretty cool, right?

Remember, good authentication UX can make or break your app, and Google One Tap is a great way to reduce friction in the sign-in process.

Happy coding! 🚀


Found this helpful? Don't forget to share it with other developers who might find it useful! If you run into any issues, feel free to drop a comment below.


Leave a comment

Responses

You may also like

Pattern 04

Lets work together on your next project

Collaboration is key! Lets join forces and combine our skills to tackle your next project with a powerful energy that guarantees success.