# Supabase
URL: /guides/add-authentication/supabase

Supabase Auth is a complete authentication solution that integrates seamlessly with your Supabase database. This guide shows how to integrate it with Tambo in a Next.js application.

<Callout type="info" title="Prerequisites">
  This guide assumes you've already set up Supabase Auth in your Next.js
  application, including the auth callback route. If you haven't, follow the
  [Supabase Next.js Quick
  Start](https://supabase.com/docs/guides/auth/quickstarts/nextjs) first.
</Callout>

<Callout type="warn" title="JWT Verification Requirement">
  Supabase Auth doesn't support asymmetric JWT verification. You **must**
  disable JWT verification in your Tambo project settings (Settings > User
  Authentication > Verification Strategy > None) when using Supabase Auth.
</Callout>

## Installation

Install the required packages:

```bash
npm install @supabase/supabase-js @tambo-ai/react
```

## Integration Options

### Server-Side Token Retrieval (Recommended)

Use this approach for better security and performance, especially when you don't need real-time authentication state changes.

```tsx title="app/layout.tsx"
import { createServerClient } from "@supabase/supabase-js";
import { cookies } from "next/headers";
import ClientLayout from "./client-layout";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        get(name: string) {
          return cookies().get(name)?.value;
        },
      },
    },
  );

  const {
    data: { session },
  } = await supabase.auth.getSession();

  return (
    <html lang="en">
      <body>
        <ClientLayout userToken={session?.access_token}>
          {children}
        </ClientLayout>
      </body>
    </html>
  );
}
```

```tsx title="app/client-layout.tsx"
"use client";

import { TamboProvider } from "@tambo-ai/react";
import { ReactNode } from "react";

interface ClientLayoutProps {
  children: ReactNode;
  userToken?: string;
}

export default function ClientLayout({
  children,
  userToken,
}: ClientLayoutProps) {
  return <TamboProvider userToken={userToken}>{children}</TamboProvider>;
}
```

### Client-Side Token Retrieval

Use this approach when you need real-time authentication state management or client-side routing with authentication guards.

```tsx title="app/client-layout.tsx"
"use client";

import { TamboProvider } from "@tambo-ai/react";
import { createClient } from "@/lib/supabase";
import { ReactNode, useEffect, useState } from "react";

interface ClientLayoutProps {
  children: ReactNode;
}

export default function ClientLayout({ children }: ClientLayoutProps) {
  const [accessToken, setAccessToken] = useState<string | undefined>();
  const supabase = createClient();

  useEffect(() => {
    // Get initial session
    const getInitialSession = async () => {
      const {
        data: { session },
      } = await supabase.auth.getSession();
      setAccessToken(session?.access_token);
    };

    getInitialSession();

    // Listen for auth changes
    const {
      data: { subscription },
    } = supabase.auth.onAuthStateChange((_event, session) => {
      setAccessToken(session?.access_token);
    });

    return () => subscription.unsubscribe();
  }, [supabase]);

  return <TamboProvider userToken={accessToken}>{children}</TamboProvider>;
}
```

## Usage

Once configured, you can use Tambo components throughout your application:

```tsx title="app/dashboard/page.tsx"
import { MessageThreadFull } from "@components/tambo/message-thread-full";

export default function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <MessageThreadFull />
    </div>
  );
}
```

## Supabase-Specific Features

### Automatic Token Refresh

Supabase automatically handles token refresh in the background. When tokens expire, Supabase will automatically refresh them, and the TamboProvider will receive the updated token through the auth state change listener.

### Session Management

Supabase provides robust session management across tabs and devices. The auth state change listener ensures that authentication state stays synchronized across your application.

<Callout type="info" title="Why Disable JWT Verification">
  Supabase uses symmetric JWT signing (HMAC-SHA256) rather than asymmetric
  signing (RS256). Tambo's JWT verification is designed for asymmetric tokens
  from OAuth providers. Since Supabase handles authentication security,
  disabling JWT verification in Tambo is safe and recommended.
</Callout>
