Next.js 14 + Auth.js实现登录/登出后首页显示Toast提示
实现登录/登出后的Toast提示(Next.js 14 + Auth.js)
核心思路
通过在登录/登出跳转时携带查询参数(如?success=login),在首页检测参数后显示Toast,随后移除参数避免重复触发。
步骤1:修改登录/登出跳转逻辑
在调用Auth.js的signIn和signOut方法时,指定跳转URL并携带状态参数:
登录按钮代码
'use client'; import { signIn } from 'next-auth/react'; export function LoginButton() { return ( <button onClick={() => signIn('google', { redirectTo: '/?success=login' })} className="px-4 py-2 bg-blue-500 text-white rounded" > 用Google登录 </button> ); }
登出按钮代码
'use client'; import { signOut } from 'next-auth/react'; export function LogoutButton() { return ( <button onClick={() => signOut({ redirectTo: '/?success=logout' })} className="px-4 py-2 bg-red-500 text-white rounded" > 登出 </button> ); }
步骤2:首页检测参数并显示Toast
在首页组件(app/page.js,App Router)中,通过useSearchParams获取查询参数,控制Toast的显示与隐藏,同时移除参数避免刷新后重复提示:
'use client'; import { useEffect, useState } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; export default function Home() { const searchParams = useSearchParams(); const router = useRouter(); const [toastMsg, setToastMsg] = useState(''); useEffect(() => { const successType = searchParams.get('success'); if (!successType) return; // 设置对应提示文本 if (successType === 'login') { setToastMsg('You are successfully authenticated'); } else if (successType === 'logout') { setToastMsg('You have successfully logged out'); } // 移除URL中的查询参数,避免刷新页面重复显示 router.replace('/', { scroll: false }); // 3秒后自动隐藏Toast const timer = setTimeout(() => setToastMsg(''), 3000); return () => clearTimeout(timer); }, [searchParams, router]); return ( <div className="min-h-screen p-8"> {/* 首页其他内容 */} {toastMsg && ( <div className="fixed top-4 right-4 bg-green-600 text-white px-6 py-3 rounded-lg shadow-lg z-50"> {toastMsg} </div> )} </div> ); }
(可选)Pages Router 适配方案
如果使用Pages Router,逻辑类似,改用useRouter获取query参数:
'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; export default function Home() { const router = useRouter(); const [toastMsg, setToastMsg] = useState(''); useEffect(() => { const { success } = router.query; if (!success) return; if (success === 'login') { setToastMsg('You are successfully authenticated'); } else if (success === 'logout') { setToastMsg('You have successfully logged out'); } // 移除查询参数 router.replace('/', undefined, { shallow: true }); const timer = setTimeout(() => setToastMsg(''), 3000); return () => clearTimeout(timer); }, [router.query]); return ( {/* 页面内容 + Toast */} ); }
注意事项
- 确保Auth.js配置中未拦截自定义跳转URL:在
auth.js的callbacks.redirect中允许自定义跳转:
export const authOptions = { providers: [/* Google配置 */], callbacks: { redirect({ url, baseUrl }) { // 允许以baseUrl开头的自定义跳转 if (url.startsWith(baseUrl)) return url; return baseUrl; }, }, };
- 可以根据需求自定义Toast的样式(如颜色、位置、动画),或集成第三方Toast库简化开发。
内容的提问来源于stack exchange,提问作者2dar
相关产品推荐
相关产品推荐

