next-intl icon indicating copy to clipboard operation
next-intl copied to clipboard

[Docs]: Example: Integrating with Supabase Authentication

Open amannn opened this issue 1 year ago • 5 comments

Link to page

https://next-intl-docs.vercel.app/docs/routing/middleware

Describe the problem

@supabase/auth-helpers-nextjs is deprecated:

We generally recommend using the new @supabase/ssr package instead of auth-helpers. @supabase/ssr takes the core concepts of the Auth Helpers package and makes them available to any server framework. Check out the migration doc to learn more.

It would be helpful if we update our example in the docs too. I don't have any experience with Supabase, therefore it would be helpful if someone who actively uses Supabase could adapt this.

@wscourge Since you've provided https://github.com/amannn/next-intl/pull/673, do you by chance know how to upgrade?

amannn avatar Dec 12 '23 11:12 amannn

I'll keep in mind doing it once done in my project.

wscourge avatar Dec 13 '23 06:12 wscourge

Hi, Any update on this ? @wscourge have you given it a try?

abiddraws avatar Dec 22 '23 10:12 abiddraws

Nope. Have you?

wscourge avatar Dec 25 '23 08:12 wscourge

You need to create a Request/Response for client for serverless. Here is a generic function that allows to choose cookie methods:

import { CookieMethods, createServerClient } from '@supabase/ssr'

interface ComposeDbServerClientProps {
  cookieMethods?: () => CookieMethods
}

/**
 * Creates a server client for the database.
 * You can view the examples: https://supabase.com/docs/guides/auth/server-side/creating-a-client?environment=route-handler#creating-a-client
 */
export const composeDbServerClient = ({ cookieMethods }: ComposeDbServerClientProps) => {
  {
    if (!cookieMethods) {
      throw new Error('cookieMethods are required!')
    }

    const dbServerClient = createServerClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
      {
        cookies: cookieMethods(),
        auth: {
          flowType: 'pkce',
          autoRefreshToken: true,
          persistSession: true,
          detectSessionInUrl: true,
        },
      },
    )

    return {
      dbServerClient,
    }
  }
}

once you have compose you can create a client for SSR or Middleware environment (they have different inputs)

import { type CookieOptions } from '@supabase/ssr'

import { getCookie, setCookie } from 'cookies-next'
import { type NextRequest, type NextResponse } from 'next/server'
import { composeDbServerClient } from './compose-db-server-client'

/**
 * Function that returns an object with methods for handling cookies. Can be used as an argument to the createDbServerClient method in server scenarios.
 */
export const composeDbReqResClient = (req: NextRequest, res: NextResponse) => {
  return composeDbServerClient({
    cookieMethods: () => ({
      get(name: string) {
        return getCookie(name, { req, res })
      },
      set(name: string, value: string, options: CookieOptions) {
        return setCookie(name, value, { req, res, ...options })
      },
      remove(name: string, options: CookieOptions) {
        return setCookie(name, '', { req, res, ...options })
      },
    }),
  })
}

once you are able to create a dbClient for serverles, it's same old, same old as in the docs:

export async function middleware(req: NextRequest) {

  try {
    const res = i18nMiddleware(req)
    const { dbServerClient } = composeDbReqResClient(req, res)
    await dbServerClient.auth.getSession() // automatically refreshes the session if expired
    
    return res
  }
  
  ...

Hope it helps.

cookies-next package is pretty important here, abstracts a way a lot of boilerplate.

mkbctrl avatar Jan 06 '24 01:01 mkbctrl

Just made this PR, hope it helps: #856

flixlix avatar Feb 11 '24 15:02 flixlix

There's another update coming to the Supabase authentication docs here: https://github.com/amannn/next-intl/pull/1260

amannn avatar Aug 20 '24 13:08 amannn