DEV Community

Cover image for [Client] Auth with Next.js 14 & Supabase
CodewithGuillaume
CodewithGuillaume

Posted on

[Client] Auth with Next.js 14 & Supabase

If you have encountered problems setting up authentication with Next.js 14 and Supabase on the client side, this is probably the article you need to read.

To summarize: we want to use auth on Next.js 14 on the client side with Supabase. The new package @supabase/auth-helpers-nextjs offers us new methods to implement our authentication system.

However, after consulting Supabase Auth with the Next.js App Router written by Jon Meyers, I still couldn't implement the client-side solution. For some reason, middleware wouldn't catch my session.

I don't know if I was getting things mixed up, but after hours of research, after reading Andrew Smith's comment on Stackoverflow I managed to find the solution.

Here's how to proceed:

1/ Only use @supabase/auth-helpers-nextjs & not @supabase/supabase-js

2/ Create a client to export with @supabase/auth-helpers-nextjs

// @lib/supabase.ts

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

export const supabase = createClientComponentClient()
Enter fullscreen mode Exit fullscreen mode

3/ Use it everywhere (login example)

// login.ts

...
const login = async () => {
    const { email, password } = data;
    try {
      setLoading(true);

      const { data, error } = await supabase
        .auth
        .signInWithPassword({
          email,
          password
        })

      if (error) return setError('Sorry impossible to login.');

      if (data) {
        const { user } = data
        const { access_token, refresh_token } = data.session
        await supabase.auth.setSession({
          access_token,
          refresh_token
        })
        setUser(user)
        router.refresh() // very important! we'll catch session on middleware
      }

    } catch (error: any) {
      throw new Error(error)
    } finally {
      setLoading(false);
    }
  }
...
Enter fullscreen mode Exit fullscreen mode

4/ Setup a middleware:


// middleware.ts

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

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

  const supabase = createMiddlewareClient({ req, res })

  const {
    data: {
      session
    }
  } = await supabase.auth.getSession()

  if (!session) {
    return NextResponse.rewrite(new URL('/login', req.url))
  }

  return res
}

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ]
}
Enter fullscreen mode Exit fullscreen mode

5/ You're good to go.

Guillaume Duhan

Top comments (0)