Skip to content

Commit c3bf735

Browse files
authored
Chore: refactor to use server actions in with-supabase example (#57858)
### What? [1] Use Server Actions for auth [2] Use Geist font [3] Address warning about `metadataBase` in console ### Why? [1] The co-location of Login page and authentication logic is simpler for beginners [2] Looks nice [3] Avoid confusing people with the starter template printing warnings ### How? [1] Refactor Route Handlers to Server Actions [2] Install font and set to `html` [3] Explicitly declare the default value for `metadataBaseUrl`
1 parent 9658cf7 commit c3bf735

File tree

8 files changed

+79
-118
lines changed

8 files changed

+79
-118
lines changed

examples/with-supabase/app/auth/sign-in/route.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.

examples/with-supabase/app/auth/sign-out/route.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

examples/with-supabase/app/auth/sign-up/route.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

examples/with-supabase/app/layout.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import { GeistSans } from 'geist/font'
12
import './globals.css'
23

4+
const defaultUrl = process.env.VERCEL_URL
5+
? `https://${process.env.VERCEL_URL}`
6+
: 'http://localhost:3000'
7+
38
export const metadata = {
9+
metadataBase: new URL(defaultUrl),
410
title: 'Next.js and Supabase Starter Kit',
511
description: 'The fastest way to build apps with Next.js and Supabase',
612
}
@@ -11,7 +17,7 @@ export default function RootLayout({
1117
children: React.ReactNode
1218
}) {
1319
return (
14-
<html lang="en">
20+
<html lang="en" className={GeistSans.className}>
1521
<body className="bg-background text-foreground">
1622
<main className="min-h-screen flex flex-col items-center">
1723
{children}

examples/with-supabase/app/login/messages.tsx

Lines changed: 0 additions & 23 deletions
This file was deleted.

examples/with-supabase/app/login/page.tsx

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,57 @@
11
import Link from 'next/link'
2-
import Messages from './messages'
2+
import { headers, cookies } from 'next/headers'
3+
import { createClient } from '@/utils/supabase/server'
4+
import { redirect } from 'next/navigation'
5+
6+
export default function Login({
7+
searchParams,
8+
}: {
9+
searchParams: { message: string }
10+
}) {
11+
const signIn = async (formData: FormData) => {
12+
'use server'
13+
14+
const email = formData.get('email') as string
15+
const password = formData.get('password') as string
16+
const cookieStore = cookies()
17+
const supabase = createClient(cookieStore)
18+
19+
const { error } = await supabase.auth.signInWithPassword({
20+
email,
21+
password,
22+
})
23+
24+
if (error) {
25+
return redirect('/login?message=Could not authenticate user')
26+
}
27+
28+
return redirect('/')
29+
}
30+
31+
const signUp = async (formData: FormData) => {
32+
'use server'
33+
34+
const origin = headers().get('origin')
35+
const email = formData.get('email') as string
36+
const password = formData.get('password') as string
37+
const cookieStore = cookies()
38+
const supabase = createClient(cookieStore)
39+
40+
const { error } = await supabase.auth.signUp({
41+
email,
42+
password,
43+
options: {
44+
emailRedirectTo: `${origin}/auth/callback`,
45+
},
46+
})
47+
48+
if (error) {
49+
return redirect('/login?message=Could not authenticate user')
50+
}
51+
52+
return redirect('/login?message=Check email to continue sign in process')
53+
}
354

4-
export default function Login() {
555
return (
656
<div className="flex-1 flex flex-col w-full px-8 sm:max-w-md justify-center gap-2">
757
<Link
@@ -26,9 +76,8 @@ export default function Login() {
2676
</Link>
2777

2878
<form
29-
className="flex-1 flex flex-col w-full justify-center gap-2 text-foreground"
30-
action="/auth/sign-in"
31-
method="post"
79+
className="animate-in flex-1 flex flex-col w-full justify-center gap-2 text-foreground"
80+
action={signIn}
3281
>
3382
<label className="text-md" htmlFor="email">
3483
Email
@@ -53,12 +102,16 @@ export default function Login() {
53102
Sign In
54103
</button>
55104
<button
56-
formAction="/auth/sign-up"
105+
formAction={signUp}
57106
className="border border-foreground/20 rounded-md px-4 py-2 text-foreground mb-2"
58107
>
59108
Sign Up
60109
</button>
61-
<Messages />
110+
{searchParams?.message && (
111+
<p className="mt-4 p-4 bg-foreground/10 text-foreground text-center">
112+
{searchParams.message}
113+
</p>
114+
)}
62115
</form>
63116
</div>
64117
)

examples/with-supabase/components/AuthButton.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createClient } from '@/utils/supabase/server'
22
import Link from 'next/link'
33
import { cookies } from 'next/headers'
4+
import { redirect } from 'next/navigation'
45

56
export default async function AuthButton() {
67
const cookieStore = cookies()
@@ -10,10 +11,19 @@ export default async function AuthButton() {
1011
data: { user },
1112
} = await supabase.auth.getUser()
1213

14+
const signOut = async () => {
15+
'use server'
16+
17+
const cookieStore = cookies()
18+
const supabase = createClient(cookieStore)
19+
await supabase.auth.signOut()
20+
return redirect('/login')
21+
}
22+
1323
return user ? (
1424
<div className="flex items-center gap-4">
1525
Hey, {user.email}!
16-
<form action="/auth/sign-out" method="post">
26+
<form action={signOut}>
1727
<button className="py-2 px-4 rounded-md no-underline bg-btn-background hover:bg-btn-background-hover">
1828
Logout
1929
</button>

examples/with-supabase/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"@supabase/ssr": "latest",
1010
"@supabase/supabase-js": "latest",
1111
"autoprefixer": "10.4.15",
12+
"geist": "^1.0.0",
1213
"next": "latest",
1314
"postcss": "8.4.29",
1415
"react": "18.2.0",

0 commit comments

Comments
 (0)