Monza Motors uses Supabase for email and password authentication with server-side rendering (SSR) cookie-based session management via theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Jason-AML/MonzaSport-Nextjs/llms.txt
Use this file to discover all available pages before exploring further.
@supabase/ssr package. This approach means the session is stored in an HTTP-only cookie and is available to both client components and Next.js server components or API routes — eliminating the need to pass auth tokens manually between layers.
Authentication Flow
Register at /register
The user fills in an email and password in
RegisterForm. On submit, registerService() calls supabase.auth.signUp(). If the email is already registered, the response includes an empty identities array and the form surfaces an error toast rather than proceeding.Sign in at /login
The user fills in their credentials in
LoginForm. On submit, signIn() calls supabase.auth.signInWithPassword(). A successful sign-in shows a welcome toast and redirects to /.Session stored in cookies
The Supabase SSR client automatically writes the access and refresh tokens to cookies on the response. Subsequent requests include these cookies, so the server can validate the session without an extra round trip to Supabase.
AuthProvider synchronises client state
AuthProvider wraps the entire app. It is initialised with the initialUser value resolved server-side, then subscribes to supabase.auth.onAuthStateChange to keep the React context in sync whenever the user signs in or out in any tab.Client-side Functions
Three functions are exported fromsrc/services/auth/auth.client.js. They all use the browser Supabase client initialised from the public anon key.
signIn and signOut throw on error so callers can catch and display user-facing messages. registerService returns the raw Supabase response instead, which lets RegisterForm inspect data.user.identities to detect duplicate accounts before showing a success message.
Server-side User Retrieval
getUser() in src/services/auth/auth.server.js uses a server-only Supabase client created with @supabase/ssr’s cookie store. It validates the session against Supabase’s auth server and returns the user object, or null if the session is missing or invalid.
AuthProvider
AuthProvider is a client-side context provider defined in src/providers/AuthProvider.jsx. It accepts an initialUser prop (typically the result of getUser() called in the root layout server component) so the initial render never flickers — the user object is already populated before the first paint.
After mounting, it subscribes to onAuthStateChange. Whenever the Supabase auth state changes (sign-in, sign-out, token refresh), the user state is updated and all consumers re-render automatically. The subscription is cleaned up on unmount.
Consume the context anywhere in the component tree with the useAuth hook:
user— the SupabaseUserobject, ornullwhen not signed in.loading—trueduring the initial auth state resolution;falseonce the state is known.
Route Protection
ThePOST /api/checkout route calls getUser() at the very start of the handler. If the call returns null, it immediately responds with HTTP 401 Unauthorized and does not create a Stripe session. On the client side, the Detail component’s handleStripe function checks for a 401 status and redirects the user to /error, prompting them to sign in before attempting to purchase.
SUPABASE_SERVICE_ROLE_KEY is only used server-side inside the /api/chat route, where it bypasses row-level security to read and write the messages table on behalf of any user. All authentication operations — sign-up, sign-in, sign-out, and session validation — use the public anon key (NEXT_PUBLIC_SUPABASE_ANON_KEY), which is safe to expose in the browser.