You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS13中Supabase useSession初始返回null致渲染闪现问题

解决NextJS 13中Supabase登录页Auth组件闪现问题

方案1:使用服务端组件(App Router推荐)

NextJS 13 App Router下,服务端组件可在请求阶段直接获取session,提前完成重定向逻辑,完全避免客户端的组件闪现问题。

// app/login/page.js(服务端组件)
import { getServerSession } from '@supabase/auth-helpers-nextjs'
import { redirect } from 'next/navigation'
import AuthClient from './AuthClient'

export default async function LoginPage() {
  const session = await getServerSession()

  if (session) {
    redirect('/')
  }

  return <AuthClient />
}

// app/login/AuthClient.js(客户端组件)
'use client'

import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
import { useSupabaseClient } from '@supabase/auth-helpers-react'
import { Box } from '@mantine/core'

export default function AuthClient() {
  const supabase = useSupabaseClient()

  return (
    <Box sx={{
      paddingLeft: '35vw',
      paddingRight: '35vw',
      paddingTop: '10vh',
    }}>
      <Auth
        redirectTo="http://localhost:3000"
        supabaseClient={supabase}
        theme="dark"
        appearance={{ theme: ThemeSupa }}
        providers={['google', 'github', 'linkedin']}
      />
    </Box>
  )
}

服务端组件会在请求时先校验session,若用户已登录直接重定向至首页,不会向客户端发送Auth组件的渲染代码,从根源上解决闪现问题。

方案2:客户端组件添加加载状态退避

如果必须使用客户端组件,可通过useSession返回的status字段判断会话加载状态,在加载完成前显示占位内容,避免Auth组件提前渲染。

'use client'

import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
import { useSession, useSupabaseClient } from '@supabase/auth-helpers-react'
import { Box, Loader } from '@mantine/core'
import { useRouter } from 'next/router'
import { useEffect } from 'react'

export default function AuthComp() {
  const supabase = useSupabaseClient()
  const { data: session, status } = useSession()
  const router = useRouter()

  useEffect(() => {
    if (status === 'authenticated') {
      router.push('/')
    }
  }, [status, router])

  // 会话加载中时显示加载器
  if (status === 'loading') {
    return (
      <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
        <Loader size="lg" />
      </Box>
    )
  }

  // 未登录时渲染Auth组件
  if (status === 'unauthenticated') {
    return (
      <Box sx={{
        paddingLeft: '35vw',
        paddingRight: '35vw',
        paddingTop: '10vh',
      }}>
        <Auth
          redirectTo="http://localhost:3000"
          supabaseClient={supabase}
          theme="dark"
          appearance={{ theme: ThemeSupa }}
          providers={['google', 'github', 'linkedin']}
        />
      </Box>
    )
  }

  // 已登录时返回空,等待useEffect触发重定向
  return null
}

status字段包含loading、authenticated、unauthenticated三种状态,通过它精准控制渲染逻辑,避免未完成校验时显示登录界面。

方案3:使用Middleware全局拦截

通过NextJS Middleware在请求到达页面之前就校验用户会话,直接重定向已登录用户,完全绕过登录页的渲染流程。

创建middleware.js文件:

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

export async function middleware(req) {
  const res = NextResponse.next()
  const supabase = createMiddlewareClient({ req, res })

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

  // 已登录用户访问登录页时,直接重定向至首页
  if (session && req.nextUrl.pathname === '/login') {
    return NextResponse.redirect(new URL('/', req.url))
  }

  return res
}

// 指定中间件生效的路径
export const config = {
  matcher: ['/login'],
}

Middleware在服务端层面拦截请求,提前完成会话校验,已登录用户根本不会加载登录页组件,彻底解决闪现问题。

内容的提问来源于stack exchange,提问作者Victor M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:32:12