Skip to content

Instantly share code, notes, and snippets.

@caillou
Created August 23, 2023 18:29
Show Gist options
  • Save caillou/973dd696e125b0cf46a72ebfe52d3954 to your computer and use it in GitHub Desktop.
Save caillou/973dd696e125b0cf46a72ebfe52d3954 to your computer and use it in GitHub Desktop.
Next.js App Router with supabase.signInWithOAuth()

Next.js App Router with supabase.signInWithOAuth()

Client-Side

'use client';

import { createClientComponentClient } from '@supabase/auth-helpers-nextjs';

const getURL = () => {
  let url =
    process?.env?.NEXT_PUBLIC_SITE_URL ?? // Set this to your site URL in production env.
    process?.env?.NEXT_PUBLIC_VERCEL_URL ?? // Automatically set by Vercel.
    'http://localhost:3000/';

  // Make sure to include https:// when not localhost.
  url = url.includes('http') ? url : `https://${url}`;
  // Make sure to including trailing /.
  url = url.charAt(url.length - 1) === '/' ? url : `${url}/`;
  return url;
};

export default function LoginButton() {
  const supabase = createClientComponentClient();

  const signIn = () => {
    supabase.auth.signInWithOAuth({
      provider: 'google',
      options: {
        redirectTo: `${getURL()}auth/callback`,
      },
    });
  };

  return (
    <button
      type="button"
      className="rounded-md bg-btn-background px-4 py-2 no-underline hover:bg-btn-background-hover"
      onClick={signIn}
    >
      Login
    </button>
  );
}

middleware.ts

import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export async function middleware(req: NextRequest) {
  const res = NextResponse.next();

  // Create a Supabase client configured to use cookies
  const supabase = createMiddlewareClient({ req, res });

  // Refresh session if expired - required for Server Components
  // https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-session-with-middleware
  await supabase.auth.getSession();

  return res;
}

app/auth/callback/route.ts

import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
  // The /auth/callback route is required for the server-side auth flow implemented
  // by the Auth Helpers package. It exchanges an auth code for the user's session.
  // https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-sign-in-with-code-exchange
  const requestUrl = new URL(request.url);
  const code = requestUrl.searchParams.get('code');

  if (code) {
    const supabase = createRouteHandlerClient({ cookies });
    await supabase.auth.exchangeCodeForSession(code);
  }

  // URL to redirect to after sign in process completes
  return NextResponse.redirect(requestUrl.origin);
}
@caillou
Copy link
Author

caillou commented Aug 23, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment