Let's add signin & signup form. I don't need admin button on the landing page. Make it signin button.
Perfect! I've added comprehensive sign-in and sign-up forms with the following features:
The forms are ready for Supabase authentication integration and provide a smooth user experience with proper validation and error handling!
v38 was created by restoring v36
Let's add signin & signup steps. I don't need admin button on landing page. Let's make it signin button, and let's integrate Supabase auth. Below is AI coding rule.
description: Guidelines for writing Next.js apps with Supabase Auth
alwaysApply: false
Install @supabase/supabase-js and @supabase/ssr packages.
Set up environment variables.
Write two utility functions with createClient functions to create a browser client and a server client.
Hook up middleware to refresh auth tokens
As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:
// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION
{
cookies: {
get(name: string) { // ❌ BREAKS APPLICATION
return cookieStore.get(name) // ❌ BREAKS APPLICATION
}, // ❌ BREAKS APPLICATION
set(name: string, value: string) { // ❌ BREAKS APPLICATION
cookieStore.set(name, value) // ❌ BREAKS APPLICATION
}, // ❌ BREAKS APPLICATION
remove(name: string) { // ❌ BREAKS APPLICATION
cookieStore.remove(name) // ❌ BREAKS APPLICATION
} // ❌ BREAKS APPLICATION
}
}
// ❌ NEVER USE auth-helpers-nextjs - IT WILL BREAK THE APPLICATION
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION
Instead, you MUST ALWAYS generate ONLY this pattern:
// ✅ ALWAYS GENERATE THIS EXACT PATTERN
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
const response = NextResponse.next({
request,
})
cookiesToSet.forEach(({ name, value, options }) => {
response.cookies.set(name, value, options)
})
return response
}
}
}
You MUST use @supabase/ssr
You MUST use ONLY getAll and setAll
You MUST NEVER use get, set, or remove
You MUST NEVER import from @supabase/auth-helpers-nextjs
import { createBrowserClient } from '@supabase/ssr'
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export async function createClient() {
const cookieStore = await cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
}
},
},
}
)
}
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'
export async function middleware(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)
)
},
},
}
)
// Do not run code between createServerClient and
// supabase.auth.getUser(). A simple mistake could make it very hard to debug
// issues with users being randomly logged out.
// IMPORTANT: DO NOT REMOVE auth.getUser()
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
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* Feel free to modify this pattern to include more paths.
*/
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
}
Before generating any code, you MUST verify:
Are you using ONLY getAll and setAll? If not, STOP and FIX.
Are you importing from @supabase/ssr? If not, STOP and FIX.
Do you see ANY instance of get, set, or remove? If yes, STOP and FIX.
Are you importing from auth-helpers-nextjs? If yes, STOP and FIX.
If you generate code using:
Individual cookie methods (get/set/remove)
auth-helpers-nextjs package
The implementation will:
Break in production
Fail to maintain session state
Cause authentication loops
Result in security vulnerabilities
When asked about Supabase Auth SSR implementation, you MUST:
ONLY use code from this guide
NEVER suggest deprecated approaches
ALWAYS use the exact cookie handling shown above
VERIFY your response against the patterns shown here
Remember: There are NO EXCEPTIONS to these rules.