> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hanko.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Using Hanko with Supabase

> This guide showcases how to add new user info, like user ID and email to the Supabase database, when users sign up with Hanko. Jump to [Nextjs guide](/quickstarts/fullstack/next) to learn how to add Hanko Auth in your Next App.

<div class="hidden">
  # Hanko Supabase Integration Guide

  **About Hanko**:

  Hanko is a modern open source authentication solution and the fastest way you integrate passkeys, 2FA, SSO, and more—with full control over your data. Move between self-hosted and Hanko Cloud anytime. No lock-in. Just Auth how it should be: secure, user friendly, and fully yours.

  **What This Guide Covers**: This guide demonstrates how to integrate Hanko authentication with Supabase database. You'll learn to automatically sync user data between Hanko and Supabase, creating user profiles and managing authentication state across both platforms.

  **Key Technologies**:

  * Hanko Elements (Authentication)
  * Supabase (Database & Backend)
  * Next.js (React Framework)
  * TypeScript
  * Supabase JavaScript Client
  * Database Schema Design

  **Prerequisites**:

  * Basic knowledge of React/Next.js
  * Understanding of database concepts
  * Node.js development environment
  * Active Hanko project configured
  * Supabase account and project

  **Tasks You'll Complete**:

  1. Set up Supabase project and database
  2. Create users table with proper schema
  3. Configure Supabase client in your application
  4. Build API endpoint for user synchronization
  5. Integrate user sync with Hanko authentication
  6. Test user creation and data flow
</div>

This guide uses Next.js, but you can apply the same concepts to other frameworks or languages. We're expanding our framework examples, so stay tuned for more!

<Steps>
  <Step title="Create Supabase account">
    Sign up for a [Supabase](https://supabase.com/) account if you don't have one already.
  </Step>

  <Step title="Create new project">
    From the Supabase dashboard, click 'New Project' to create a project for your application.

    <Frame>
      <img src="https://mintcdn.com/hanko/2iB49Inz8wUnw70r/images/supabase/create-new-project.png?fit=max&auto=format&n=2iB49Inz8wUnw70r&q=85&s=1f809c401387d46ee76e950bccba1776" alt="create new project" width="500" style={{ borderRadius: "0.5rem" }} data-path="images/supabase/create-new-project.png" />
    </Frame>
  </Step>

  <Step title="Create users table">
    In your project dashboard, navigate to 'Database' and create a new 'users' table.
    This table will store user information from Hanko. Add these columns beyond the default 'id':

    * 'user\_id' (to match Hanko's user ID)
    * 'email' (to store user email addresses)

    <Frame>
      <img src="https://mintcdn.com/hanko/2iB49Inz8wUnw70r/images/supabase/create-new-table.png?fit=max&auto=format&n=2iB49Inz8wUnw70r&q=85&s=570a92748dacd0e28679085f0f5d9dbd" alt="create new project" width="500" style={{ borderRadius: "0.5rem" }} data-path="images/supabase/create-new-table.png" />
    </Frame>
  </Step>

  <Step title="Configure environment variables">
    In your project dashboard, go to 'Project Settings' > 'API'. Copy the 'URL' and 'service\_role' key, then add them to your `.env.local` file.

    ```sh .env.local theme={null}
    NEXT_PUBLIC_HANKO_API_URL=https://f4****-4802-49ad-8e0b-3d3****ab32.hanko.io

    NEXT_PUBLIC_SUPABASE_PROJECT_URL=YOUR_SUPABASE_PROJECT_URL
    SUPABASE_SERVICE_ROLE_KEY=YOUR_SUPABASE_SERVICE_ROLE_KEY
    ```
  </Step>

  <Step title="Install Supabase JavaScript Client">
    Add the Supabase client library to your application (assuming Hanko Auth is already configured).

    <CodeGroup>
      ```bash npm theme={null}
      npm install @supabase/supabase-js
      ```

      ```bash pnpm theme={null}
      pnpm add @supabase/supabase-js
      ```

      ```bash yarn theme={null}
      yarn add @supabase/supabase-js
      ```
    </CodeGroup>
  </Step>

  <Step title="Set up Supabase Client">
    ```ts lib/supabase.ts theme={null}
    import { createClient } from "@supabase/supabase-js";

    export const supabase = createClient(
      process.env.NEXT_PUBLIC_SUPABASE_PROJECT_URL!,
      process.env.SUPABASE_SERVICE_ROLE_KEY!
    );
    ```
  </Step>

  <Step title="Create user synchronization API">
    Build an API endpoint to sync user data between Hanko and Supabase.

    ```ts app/api/create-user/route.ts theme={null}
    import { NextResponse } from "next/server";
    import { supabase } from "@/lib/supabase";

    export async function POST(req: Request, res: Response) {
      try {
        const user = await req.json();

        if (!user) {
          return new NextResponse("Unauthorized", { status: 401 });
        }

        let supauser;

        try {
          const { data, error } = await supabase
            .from("users")
            .select("*")
            .eq("user_id", user.id)
            .single();

          if (error) {
            console.error(error);
          }

          supauser = data;

          if (!supauser) {
            const { data, error } = await supabase
              .from("users")
              .insert([{ user_id: user.id, email: user.email }]);

            if (error) {
              console.error(error);
            }

            supauser = data;
          }
        } catch (error) {
          console.error(error);
        }

        const user_data = {
          ...user,
          id: supauser?.id,
        };

        return new NextResponse(JSON.stringify(user_data), { status: 200 });
      } catch (error) {
        console.error("[CREATEUSER_ERROR]", error);
        return new NextResponse("Internal Error", { status: 500 });
      }
    }
    ```
  </Step>

  <Step title="Integrate with HankoAuth component">
    Modify your Hanko authentication component to automatically sync user data when `onSessionCreated` triggers.

    ```tsx components/hanko/HankoAuth.tsx theme={null}
    "use client";

    import { useEffect, useCallback, useState } from "react";
    import { useRouter } from "next/navigation";
    import { register, Hanko } from "@teamhanko/hanko-elements";

    const hankoApi = process.env.NEXT_PUBLIC_HANKO_API_URL || '';

    export default function HankoAuth() {
      const router = useRouter();

      const [hanko, setHanko] = useState<Hanko>();

      useEffect(() => setHanko(new Hanko(hankoApi)), []);

      const redirectAfterLogin = useCallback(() => {
        // successfully logged in, redirect to a page in your application
        router.replace("/dashboard");
      }, [router]);

      useEffect(
        () =>
          hanko?.onSessionCreated(async () => {
            const user = await hanko.user.getCurrent()

            const fetchData = async () => {
              if (!user) {
                console.error('No user data')
                return
              }
              try {
                const response = await fetch('/api/create-user', {
                  method: 'POST',
                  body: JSON.stringify(user),
                })

                if (!response.ok)
                  throw new Error(`HTTP error! status: ${response.status}`)
              } catch (error) {
                console.error('Fetch Error: ', error)
              }
            }
            await fetchData()
            redirectAfterLogin();
          }),
        [hanko, redirectAfterLogin]
      );

      useEffect(() => {
        register(hankoApi).catch((error) => {
          console.error(error);
        });
      }, []);

      return <hanko-auth />;
    }
    ```
  </Step>

  <Step title="Try it yourself">
    <Card
      title="Supabase example with Nextjs"
      href="https://github.com/teamhanko/hanko-supabase"
      icon={
  <svg
    xmlns="http://www.w3.org/2000/svg"
    className="icon icon-tabler icon-tabler-external-link"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    strokeWidth="2"
    stroke="currentColor"
    fill="none"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
    <path d="M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6"></path>
    <path d="M11 13l9 -9"></path>
    <path d="M15 4h5v5"></path>
  </svg>
}
    >
      Full source code available on our GitHub
    </Card>
  </Step>
</Steps>
