Next.js Discord

Discord Forum

Should I store User in global state?

Unanswered
Polar bear posted this in #help-forum
Open in Discord
Polar bearOP
I'm using Next + supabase. I wonder if I should store User in global context (zustand) and update it in middleware (the same that checks if user is logged in and redirects it to /login if not), or can I just fetch user with await supabase.auth.getUser() whenever I need it.

12 Replies

Giant panda
Why do you want to store it in a global state, let's the middleware handle checking as you have said
Polar bearOP
What if I want to use some data from it to display it in different paths / components.
Wouldn't it be better to store it in context?
export default async function Home() {
  const supabase = createClient();

  const {
    data: { user },
  } = await supabase.auth.getUser();

  return <div>
    {
      user?.email
    }
  </div>;
}
Polar bearOP
utils/supabase.ts

import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'

export async function updateSession(request: NextRequest) {
  let supabaseResponse = NextResponse.next({
    request,
  })

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
          supabaseResponse = NextResponse.next({
            request,
          })
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options)
          )
        },
      },
    }
  )

  // IMPORTANT: Avoid writing any logic between createServerClient and
  // supabase.auth.getUser(). A simple mistake could make it very hard to debug
  // issues with users being randomly logged out.

  const {
    data: { user },
  } = await supabase.auth.getUser()

  if (
    !user &&
    !request.nextUrl.pathname.startsWith('/login') &&
    !request.nextUrl.pathname.startsWith('/auth')
  ) {
    // no user, potentially respond by redirecting the user to the login page
    const url = request.nextUrl.clone()
    url.pathname = '/login'
    return NextResponse.redirect(url)
  }

  // IMPORTANT: You *must* return the supabaseResponse object as it is. If you're
  // creating a new response object with NextResponse.next() make sure to:
  // 1. Pass the request in it, like so:
  //    const myNewResponse = NextResponse.next({ request })
  // 2. Copy over the cookies, like so:
  //    myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
  // 3. Change the myNewResponse object to fit your needs, but avoid changing
  //    the cookies!
  // 4. Finally:
  //    return myNewResponse
  // If this is not done, you may be causing the browser and server to go out
  // of sync and terminate the user's session prematurely!

  return supabaseResponse
}


This is my supabase middleware.
It already fetches user so making it store that data for populating across the app seems reasonable to me but I'm not sure
Giant panda
The problem is stale data, if you can find a way to keep that fresh, then that's fine but I would suggest not to do that, just call get user whenever u need it. It's not as bad in performance as you might think
Polar bearOP
Oh, okay
So even if I have two pages (dashboard, posts) that need the same data (lets say "posts") It's okay to fetch them on each of these pages and that will be okay because it ensures that data is fresh?
Giant panda
There are few ways to do this
One is to cache a function that fetches a data from a source using the wrapped fetch API by next js and pass the time to revalidate that data
However to do that, you have write that function in a server component or a file marked as 'use sever'
Bur the problem is that get user by supabase won't work in a server action file. It won't

It's for a client component
You can try this and confirm yourself
Let me know if you understand or u need more explanation