Skip to content
  • Integrations
  • Third-party tools

Add Kinde authentication to your Supabase project

You can use Kinde as a custom OAuth provider in Supabase so users sign in with Kinde while Supabase manages the session in your app.

This guide walks through connecting Kinde to Supabase Auth, then adding sign-in, sign-up, and logout to a Next.js app using Supabase’s signInWithOAuth method. When you’re done, you can build on this setup with a to-do app.

  • A Kinde account with Admin or Engineer permissions (sign up for free)
  • A Supabase account (sign up for free)

1. Set up a Kinde application

Link to this section
  1. Sign in to your Kinde dashboard. On the home page, select Add application.
  2. Enter a name for the application (e.g., “Supabase”) and select Back-end web as the application type. Select Save.
  3. Select Other back end from the SDK list, then select Save.
  4. Go to the Authentication page, enable the authentication methods you want (e.g., Email + Password, Google, Facebook), and select Save.
  5. Go to the Details page and copy the Domain (or Custom domain), Client ID, and Client Secret. You’ll need these in the next step.

2. Configure your Supabase project

Link to this section
  1. Sign in to your Supabase dashboard.

  2. If you don’t have a project yet, create one by selecting New Project and completing setup.

  3. Go to Authentication > CONFIGURATION > Sign In / Providers.

  4. Scroll down to the Custom Providers section and select New Provider. A window opens.

    supabase custom auth provider screen 1

  5. Enter the following details:

    • Provider Identifier: kinde
    • Display Name: (e.g., “Kinde”)
    • Configuration Method: Leave as Auto-discovery (Recommended)
  6. Enter the Issuer URL: https://<your_business>.kinde.com or your Custom domain if you have one.

  7. Enter the application details you copied from Kinde in the previous step:

    • Client ID

    • Client Secret

    • Scopes: openid, email, profile

    supabase custom auth provider screen 2

  8. Copy the Callback URL provided by Supabase. You’ll add this to Kinde next.

  9. Select Update provider.

  10. Go to your Kinde application Details page and paste the callback URL into the Allowed Callback URLs field. In the Allowed logout redirect URLs field, add your local and production app origins (for example, http://localhost:3000 and https://your-app.com) so users return to your app after logout. Select Save.

    supabase kinde callback url screen

  11. In your Supabase dashboard, go to Authentication > CONFIGURATION > URL Configuration:

    • Set the Site URL to your app origin, for example http://localhost:3000 for local development or https://your-app.com for production.
    • Under Redirect URLs, select Add URL and add your /auth/callback routes, for example http://localhost:3000/auth/callback and your production URL (https://your-app.com/auth/callback).
    • Select Save.

3. Add Kinde authentication to your Supabase app

Link to this section

Add Kinde authentication to your Supabase app with the signInWithOAuth method:

JavaScript example
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'custom:kinde',
});

See the Supabase documentation for more details.

To add Kinde authentication to a Next.js app with Supabase:

  1. To create a new Supabase Next.js project, run:

    Terminal window
    npx create-next-app -e with-supabase
  2. Add the following to your .env.local file:

    env.local
    NEXT_PUBLIC_KINDE_DOMAIN=https://<your_business>.kinde.com

    You can use either your Kinde domain (https://your_business.kinde.com) or your Custom domain (https://auth.your_business.com). Use the same domain you used for the Issuer URL in the previous step.

  3. Create the required files:

    Terminal window
    mkdir -p app/auth/callback
    touch components/login-button.tsx
    touch components/register-button.tsx
    touch app/auth/callback/route.ts
  4. Open components/login-button.tsx, enter the following code, and save the file:

    components/login-button.tsx
    "use client";
    import { createClient } from "@/lib/supabase/client";
    import { Button } from "@/components/ui/button";
    export function LoginButton() {
    const login = async () => {
    const supabase = createClient();
    await supabase.auth.signInWithOAuth({
    provider: "custom:kinde",
    options: {
    redirectTo: `${window.location.origin}/auth/callback`,
    },
    });
    };
    return (
    <Button size="sm" variant="default" onClick={login}>
    Sign in
    </Button>
    );
    }
  5. Open components/register-button.tsx, enter the following code, and save the file:

    components/register-button.tsx
    "use client";
    import { createClient } from "@/lib/supabase/client";
    import { Button } from "@/components/ui/button";
    export function RegisterButton() {
    const register = async () => {
    const supabase = createClient();
    await supabase.auth.signInWithOAuth({
    provider: "custom:kinde",
    options: {
    queryParams: {
    prompt: "create",
    },
    redirectTo: `${window.location.origin}/auth/callback`,
    },
    });
    };
    return (
    <Button size="sm" variant="default" onClick={register}>
    Sign up
    </Button>
    );
    }
  6. Open app/auth/callback/route.ts, enter the following code, and save the file:

    app/auth/callback/route.ts
    import { createClient } from "@/lib/supabase/server";
    import { NextResponse } from "next/server";
    export async function GET(request: Request) {
    const { searchParams, origin } = new URL(request.url);
    const code = searchParams.get("code");
    const nextParam = searchParams.get("next") ?? "/protected";
    // Only allow same-origin relative paths to prevent open redirects.
    const next =
    nextParam.startsWith("/") && !nextParam.startsWith("//")
    ? nextParam
    : "/protected";
    if (code) {
    const supabase = await createClient();
    const { error } = await supabase.auth.exchangeCodeForSession(code);
    if (!error) {
    return NextResponse.redirect(`${origin}${next}`);
    }
    }
    return NextResponse.redirect(`${origin}/auth/error?error=oauth_callback_failed`);
    }
  7. Open components/auth-button.tsx and replace the login/sign-up page links with OAuth buttons:

    • Remove the Link imports and <Link href="/auth/login"> / <Link href="/auth/sign-up"> buttons.

    • Add the following imports:

      import { LoginButton } from "./login-button";
      import { RegisterButton } from "./register-button";
    • Update the logged-out state to render:

      <div className="flex gap-2">
      <LoginButton />
      <RegisterButton />
      </div>
    • Keep the logged-in state the same — show the user email and <LogoutButton />.

  8. Open components/logout-button.tsx and replace the entire file with the following. This signs out of Supabase and redirects to Kinde logout:

    components/logout-button.tsx
    "use client";
    import { createClient } from "@/lib/supabase/client";
    import { Button } from "@/components/ui/button";
    export function LogoutButton() {
    const logout = async () => {
    const supabase = createClient();
    await supabase.auth.signOut();
    const kindeDomain = process.env.NEXT_PUBLIC_KINDE_DOMAIN;
    const redirect = encodeURIComponent(window.location.origin);
    window.location.href = `${kindeDomain}/logout?redirect=${redirect}`;
    };
    return <Button onClick={logout}>Logout</Button>;
    }
  9. Open lib/supabase/proxy.ts and change the unauthenticated redirect from /auth/login to /:

    lib/supabase/proxy.ts
    url.pathname = "/";
  10. Open app/protected/page.tsx and change the unauthenticated redirect from /auth/login to /:

    app/protected/page.tsx
    redirect("/");

4. Test user authentication

Link to this section
  1. Run the development server:

    Terminal window
    npm run dev
  2. Go to http://localhost:3000 and select the Sign up button. You’re redirected to the Kinde hosted registration page.

  3. Complete registration. You’re redirected to your app’s protected page.

    supabase kinde app protected page screen

  4. Go to your Kinde dashboard > Users. You’ll see the new user in the list.

  5. Go to your Supabase dashboard > Authentication > MANAGE > Users. You’ll see the same user there.

    supabase kinde user management screen

You’ve connected Kinde as a custom auth provider in Supabase and wired sign-in, sign-up, and logout into your Next.js app. New users appear in both your Kinde and Supabase dashboards.

Next, add user-specific data with PostgreSQL and Row-Level Security by building a to-do list app.