Chore: simplify with-supabase example (#57562)

### What?

[1] Simplify example
[2] Refactor `delete` method to use `cookies.set`

### Why?

[1] Make it easier to follow
[2] Fix build errors

### How?

[1] Adding comments and abstracting code into helper functions
[2] Setting cookie to empty value when removed

---------

Co-authored-by: Lee Robinson <me@leerob.io>
This commit is contained in:
Jon Meyers 2023-11-01 10:33:55 +11:00 committed by GitHub
parent e0cf4e2ebd
commit 75958bbc46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 68 deletions

View file

@ -10,6 +10,8 @@ export default async function Index() {
const cookieStore = cookies()
const canInitSupabaseClient = () => {
// This function is just for the interactive tutorial.
// Feel free to remove it once you have Supabase connected.
try {
createClient(cookieStore)
return true

View file

@ -4,21 +4,24 @@ import Code from '@/components/Code'
const create = `
create table notes (
id uuid default gen_random_uuid() primary key,
id serial primary key,
title text
);
insert into notes(title)
values('Today I connected Next.js to Supabase. It was awesome!');
values
('Today I created a Supabase project.'),
('I added some data and queried it from Next.js.'),
('It was awesome!');
`.trim()
const server = `
import { createClient } from '@/utils/supabase/server'
export const dynamic = 'force-dynamic'
import { cookies } from 'next/headers'
export default async function Page() {
const supabase = createClient()
const cookieStore = cookies()
const supabase = createClient(cookieStore)
const { data: notes } = await supabase.from('notes').select()
return <pre>{JSON.stringify(notes, null, 2)}</pre>
@ -93,11 +96,15 @@ export default function SignUpUserSteps() {
<Step title="Query Supabase data from Next.js">
<p>
Create a Supabase client and query data from an Async Server
Component.
To create a Supabase client and query data from an Async Server
Component, create a new page.tsx file at{' '}
<span className="px-2 py-1 rounded-md bg-foreground/20 text-foreground/80">
/app/notes/page.tsx
</span>{' '}
and add the following.
</p>
<Code code={server} />
<p>Alternatively, you can use a client component.</p>
<p>Alternatively, you can use a Client Component.</p>
<Code code={client} />
</Step>

View file

@ -1,74 +1,25 @@
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'
import { createClient } from '@/utils/supabase/middleware'
export async function middleware(request: NextRequest) {
// Create an unmodified response
let response = NextResponse.next({
request: {
headers: request.headers,
},
})
try {
// Create a Supabase client configured to use cookies
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return request.cookies.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
// If the cookie is updated, update the cookies for the request and response
request.cookies.set({
name,
value,
...options,
})
response = NextResponse.next({
request: {
headers: request.headers,
},
})
response.cookies.set({
name,
value,
...options,
})
},
remove(name, options) {
// If the cookie is removed, update the cookies for the request and response
request.cookies.delete({
name,
...options,
})
response = NextResponse.next({
request: {
headers: request.headers,
},
})
response.cookies.delete({
name,
...options,
})
},
},
}
)
// This `try/catch` block is only here for the interactive tutorial.
// Feel free to remove once you have Supabase connected.
const { supabase, response } = createClient(request)
// Refresh session if expired - required for Server Components
// https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-session-with-middleware
await supabase.auth.getSession()
// If the session was refreshed, the request and response cookies will have been updated
// If the session was not refreshed, the request and response cookies will be unchanged
return response
} catch (e) {
// If you are here, a Supabase client could not be created!
// This is likely because you have not set up environment variables.
// TODO: Feel free to remove this `try catch` block once you have
// your Next.js app connected to your Supabase project.
return response
// Check out http://localhost:3000 for Next Steps.
return NextResponse.next({
request: {
headers: request.headers,
},
})
}
}

View file

@ -0,0 +1,61 @@
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { type NextRequest, NextResponse } from 'next/server'
export const createClient = (request: NextRequest) => {
// Create an unmodified response
let response = NextResponse.next({
request: {
headers: request.headers,
},
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return request.cookies.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
// If the cookie is updated, update the cookies for the request and response
request.cookies.set({
name,
value,
...options,
})
response = NextResponse.next({
request: {
headers: request.headers,
},
})
response.cookies.set({
name,
value,
...options,
})
},
remove(name: string, options: CookieOptions) {
// If the cookie is removed, update the cookies for the request and response
request.cookies.set({
name,
value: '',
...options,
})
response = NextResponse.next({
request: {
headers: request.headers,
},
})
response.cookies.set({
name,
value: '',
...options,
})
},
},
}
)
return { supabase, response }
}

View file

@ -21,7 +21,7 @@ export const createClient = (cookieStore: ReturnType<typeof cookies>) => {
},
remove(name: string, options: CookieOptions) {
try {
cookieStore.delete({ name, ...options })
cookieStore.set({ name, value: '', ...options })
} catch (error) {
// The `delete` method was called from a Server Component.
// This can be ignored if you have middleware refreshing