+
+### Write utility functions to create Supabase clients
+
+TanStack Start renders matched routes on the server by default, so `beforeLoad` and `loader` run server-side on the initial request. Unlike Next.js, this means you don't need a proxy or middleware layer to keep sessions fresh — the server client reads and writes the session cookie directly on each request.
+
+Create a `lib/supabase` folder at the root of your project, or inside the `./src` folder if you are using one, then add a file for each type of client:
+
+1. **Create a browser client in `lib/supabase/client.ts`.** Use it to access Supabase from components that run in the browser.
+2. **Create a server client in `lib/supabase/server.ts`.** Use it to access Supabase from loaders, server functions, and other code that runs only on the server.
+
+<$Partial path="auth_methods.mdx" />
+
+Copy the lib utility functions below into each file:
+
+
+ <$CodeTabs>
+ <$CodeSample
+ path="/auth/tanstack/lib/supabase/client.ts"
+ meta="name=lib/supabase/client.ts"
+ language="typescript"
+ />
+ <$CodeSample
+ path="/auth/tanstack/lib/supabase/server.ts"
+ meta="name=lib/supabase/server.ts"
+ language="typescript"
+ />
+ $CodeTabs>
+
+
+### Protecting routes
+
+TanStack Start has no global middleware layer, so protect each route explicitly.
+
+To protect your routes:
+
+1. Write a server function, `fetchClaims`, that calls `supabase.auth.getClaims()` and returns the claims, or `null` if the session isn't valid.
+1. Call `fetchClaims` from a layout route's `beforeLoad` hook — for example, `_protected.tsx` — before any nested route renders, and redirect to `/login` when it returns `null`.
+
+
+
+Skipping the check inside the server function exposes private data to unauthenticated users. `beforeLoad` runs on the server for the initial request and on the client for later navigation, but either way it only gates the route's render — it doesn't stop the server function from being called directly. Because there's no proxy re-checking every request, the server function is the only checkpoint that always runs, so it must call `supabase.auth.getClaims()` to authorize the request itself.
+
+
+
+`getClaims()` validates the JWT signature on every call, the same check the Next.js Proxy relies on. Calling it inside the server function gives TanStack Start's per-route check that same guarantee, because the function runs on every request to a protected route.
+
+
+ <$CodeTabs>
+ <$CodeSample
+ path="/auth/tanstack/lib/supabase/fetch-claims-server-fn.ts"
+ meta="name=lib/supabase/fetch-claims-server-fn.ts"
+ language="typescript"
+ />
+ <$CodeSample
+ path="/auth/tanstack/routes/_protected.tsx"
+ meta="name=routes/_protected.tsx"
+ language="typescript"
+ />
+ $CodeTabs>
+
+
+Any other server function that returns or mutates private data needs this same check. Don't rely on a route being nested under `_protected` alone.
+
+## Congratulations
+
+You're done! To recap, you've successfully:
+
+- Set up a Supabase client utility to call Supabase from a browser component. You can use this if you need to call Supabase from the browser, for example to set up a realtime subscription.
+- Set up a server client utility to call Supabase from loaders and server functions.
+- Protected a route with `beforeLoad`, backed by a server function that authorizes the request itself.
+
+You can now use any Supabase features from your client or server code!
+
diff --git a/apps/docs/content/guides/getting-started/quickstarts/tanstack.mdx b/apps/docs/content/guides/getting-started/quickstarts/tanstack.mdx
index b59f80d39ad..3fe6ac2a5da 100644
--- a/apps/docs/content/guides/getting-started/quickstarts/tanstack.mdx
+++ b/apps/docs/content/guides/getting-started/quickstarts/tanstack.mdx
@@ -11,7 +11,7 @@ breadcrumb: 'Framework Quickstarts'
Create a TanStack Start app using the official CLI.
```bash
-npm create @tanstack/start@latest my-app -- --package-manager npm --toolchain biome
+npx @tanstack/cli@latest create my-app
```
## 4. Install Agent Skills (optional)
@@ -24,55 +24,87 @@ To install, run the following command in the root of your project:
npx skills add supabase/agent-skills
```
-## 5. Install the Supabase client library
+## 5. Install the Supabase client libraries
-The fastest way to get started is to use the `supabase-js` client library which provides a convenient interface for working with Supabase from a TanStack Start app.
-
-Navigate to the TanStack Start app and install `supabase-js`.
+Navigate to the TanStack Start app and install `supabase-js` and `@supabase/ssr`, the helper package that manages cookie-based sessions for server-side rendering.
```bash
-cd my-app && npm install @supabase/supabase-js
+cd my-app && npm install @supabase/supabase-js @supabase/ssr
```
## 6. Declare Supabase environment variables
-Create a `.env` file in the root of your project and populate with your Supabase connection variables that you can get from the helper below, or [from the project **Connect** panel](/dashboard/project/_?showConnect=true):
+Create a `.env.local` file in the root of your project and populate it with your Supabase connection variables. Get the values from the helper below, or [from the project **Connect** panel](/dashboard/project/_?showConnect=true&connectTab=frameworks&framework=tanstack).