Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/docs/content/guides/auth/quickstarts/nextjs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ hideToc: true

Start the development server, go to http://localhost:3000 in a browser, and you should see the contents of `app/page.tsx`.

To sign up a new user, navigate to http://localhost:3000/sign-up, and click `Sign up`. *NOTE: .env.example must be renamed to .env.local before this route becomes available*
To sign up a new user, navigate to http://localhost:3000/auth/sign-up, and click `Sign up`.

</StepHikeCompact.Details>

Expand Down
34 changes: 15 additions & 19 deletions apps/docs/content/guides/auth/server-side/creating-a-client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ To access Supabase from a Next.js app, you need 2 types of Supabase clients:
1. **Client Component client** - To access Supabase from Client Components, which run in the browser.
2. **Server Component client** - To access Supabase from Server Components, Server Actions, and Route Handlers, which run only on the server.

Since Next.js Server Components can't write cookies, you need middleware to refresh expired Auth tokens and store them.
Since Next.js Server Components can't write cookies, you need a [Proxy](https://nextjs.org/docs/app/getting-started/proxy) to refresh expired Auth tokens and store them.

The middleware is responsible for:
The Proxy is responsible for:

1. Refreshing the Auth token by calling `supabase.auth.getClaims()`.
2. Passing the refreshed Auth token to Server Components, so they don't attempt to refresh the same token themselves. This is accomplished with `request.cookies.set`.
Expand All @@ -181,7 +181,7 @@ The middleware is responsible for:

The cookies object lets the Supabase client know how to access the cookies, so it can read and write the user session data. To make `@supabase/ssr` framework-agnostic, the cookies methods aren't hard-coded. These utility functions adapt `@supabase/ssr`'s cookie handling for Next.js.

The `set` and `remove` methods for the server client need error handlers, because Next.js throws an error if cookies are set from Server Components. You can safely ignore this error because you'll set up middleware in the next step to write refreshed cookies to storage.
The `set` and `remove` methods for the server client need error handlers, because Next.js throws an error if cookies are set from Server Components. You can safely ignore this error because you'll set up Proxy in the next step to write refreshed cookies to storage.

The cookie is named `sb-<project_ref>-auth-token` by default.

Expand All @@ -201,49 +201,45 @@ The middleware is responsible for:

</Accordion>

Create a `utils/supabase` folder at the root of your project, or inside the `./src` folder if you are using one, with a file for each type of client. Then copy the utility functions for each client type.
Create a `lib/supabase` folder at the root of your project, or inside the `./src` folder if you are using one, with a file for each type of client. Then copy the lib utility functions for each client type.

<div className="mt-12">
<$CodeTabs>
<$CodeSample
path="/auth/nextjs/utils/supabase/client.ts"
meta="name=utils/supabase/client.ts"
path="/auth/nextjs/lib/supabase/client.ts"
meta="name=lib/supabase/client.ts"
language="typescript"
/>
<$CodeSample
path="/auth/nextjs/utils/supabase/server.ts"
meta="name=utils/supabase/server.ts"
path="/auth/nextjs/lib/supabase/server.ts"
meta="name=lib/supabase/server.ts"
language="typescript"
/>
</$CodeTabs>
</div>

### Hook up middleware
### Hook up proxy

The code adds a [matcher](https://nextjs.org/docs/app/building-your-application/routing/middleware#matching-paths) so the middleware doesn't run on routes that don't access Supabase.
The code adds a [matcher](https://nextjs.org/docs/app/api-reference/file-conventions/proxy#matcher) so the Proxy doesn't run on routes that don't access Supabase.

<Admonition type="danger">

Be careful when protecting pages. The server gets the user session from the cookies, which can be spoofed by anyone.

Always use `supabase.auth.getClaims()` to protect pages and user data.

_Never_ trust `supabase.auth.getSession()` inside server code such as middleware. It isn't guaranteed to revalidate the Auth token.
_Never_ trust `supabase.auth.getSession()` inside server code such as Proxy. It isn't guaranteed to revalidate the Auth token.

It's safe to trust `getClaims()` because it validates the JWT signature against the project's published public keys every time.

</Admonition>

<div className="mt-12">
<$CodeTabs>
<$CodeSample path="/auth/nextjs/proxy.ts" meta="name=proxy.ts" language="typescript" />
<$CodeSample
path="/auth/nextjs/middleware.ts"
meta="name=middleware.ts"
language="typescript"
/>
<$CodeSample
path="/auth/nextjs/utils/supabase/middleware.ts"
meta="name=utils/supabase/middleware.ts"
path="/auth/nextjs/lib/supabase/proxy.ts"
meta="name=lib/supabase/proxy.ts"
language="typescript"
/>
</$CodeTabs>
Expand All @@ -256,7 +252,7 @@ You're done! To recap, you've successfully:
- Called Supabase from a Server Action.
- Called Supabase from a Server Component.
- Set up a Supabase client utility to call Supabase from a Client Component. You can use this if you need to call Supabase from a Client Component, for example to set up a realtime subscription.
- Set up middleware to automatically refresh the Supabase Auth session.
- Set up Proxy to automatically refresh the Supabase Auth session.

You can now use any Supabase features from your client or server code!

Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/guides/database/inspect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ You can examine your database and queries for these issues using either the [Sup

The Supabase CLI comes with a range of tools to help inspect your Postgres instances for potential issues. The CLI gets the information from <a href="https://www.postgresql.org/docs/current/internals.html" target="_blank">Postgres internals</a>. Therefore, most tools provided are compatible with any Postgres databases regardless if they are a Supabase project or not.

You can find installation instructions for the the Supabase CLI <a href="/docs/guides/cli" target="_blank">here</a>.
You can find installation instructions for the Supabase CLI <a href="/docs/guides/cli" target="_blank">here</a>.

### The `inspect db` command

The inspection tools for your Postgres database are under then `inspect db` command. You can get a full list of available commands by running `supabase inspect db help`.
The inspection tools for your Postgres database are under the `inspect db` command. You can get a full list of available commands by running `supabase inspect db help`.

```
$ supabase inspect db help
Expand Down
70 changes: 14 additions & 56 deletions apps/docs/content/guides/getting-started/quickstarts/nextjs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,58 +62,7 @@ hideToc: true

</StepHikeCompact.Step>

<StepHikeCompact.Step step={4}>
<StepHikeCompact.Details title="Create Supabase client">

Create a new file at `utils/supabase/server.ts` and populate with the following.

This creates a Supabase client, using the credentials from the `env.local` file.

</StepHikeCompact.Details>

<StepHikeCompact.Code>

<$CodeTabs>

```ts name=utils/supabase/server.ts
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_PUBLISHABLE_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.
}
},
},
}
)
}
```

</$CodeTabs>

</StepHikeCompact.Code>

</StepHikeCompact.Step>

<StepHikeCompact.Step step={5}>
<StepHikeCompact.Step step={4}>
<StepHikeCompact.Details title="Query Supabase data from Next.js">

Create a new file at `app/instruments/page.tsx` and populate with the following.
Expand All @@ -127,13 +76,22 @@ hideToc: true
<$CodeTabs>

```ts name=app/instruments/page.tsx
import { createClient } from '@/utils/supabase/server';
import { createClient } from "@/lib/supabase/server";
import { Suspense } from "react";

export default async function Instruments() {
async function InstrumentsData() {
const supabase = await createClient();
const { data: instruments } = await supabase.from("instruments").select();

return <pre>{JSON.stringify(instruments, null, 2)}</pre>
return <pre>{JSON.stringify(instruments, null, 2)}</pre>;
}

export default function Instruments() {
return (
<Suspense fallback={<div>Loading instruments...</div>}>
<InstrumentsData />
</Suspense>
);
}
```

Expand All @@ -143,7 +101,7 @@ hideToc: true

</StepHikeCompact.Step>

<StepHikeCompact.Step step={6}>
<StepHikeCompact.Step step={5}>
<StepHikeCompact.Details title="Start the app">

Run the development server, go to http://localhost:3000/instruments in a browser and you should see the list of instruments.
Expand Down
Loading
Loading