maaajo
maaajo

Reputation: 1035

Multiple GoTrueClient instances detected in the same browser context

I'm creating a project with nextjs and supabase.

For an unknown reason, I'm getting the following warning in the console:

Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.

I can't seem to find what could be causing this,

This is how I initiate the supabase instance in _app.tsx:

export default function App({
  Component,
  pageProps,
}: AppProps<{ initialSession: Session }>) {
  const [supabaseClient] = useState(() => createBrowserSupabaseClient());

  return (
    <>
      <style jsx global>
        {`
          :root {
            --font-inter: ${inter.style.fontFamily};
          }
        `}
      </style>
      <SessionContextProvider
        supabaseClient={supabaseClient}
        initialSession={pageProps.initialSession}
      >
        <ChakraProvider theme={theme}>
          <Layout>
            <Component {...pageProps} />
          </Layout>
        </ChakraProvider>
      </SessionContextProvider>
    </>
  );
}

and this is how I consume the instance in components:

const ForgotPassword = () => {
  const toast = useToast();
  const supabase = useSupabaseClient();
...
}

Have you ever had an issue like that and can help me understand what I'm doing wrong?

Upvotes: 15

Views: 8364

Answers (6)

Thomas Faddegon
Thomas Faddegon

Reputation: 1

I was getting the same error because I had a client using the old supabase/auth-helpers package in addition to the new supabase/ssr package.

Upvotes: 0

Roel Leal
Roel Leal

Reputation: 677

I found a way to make works this

Create the supabase.tsx file if you are using vite or .js if you are using CRA, and put this:

import { createClient } from '@supabase/supabase-js';

const client = createClient(import.meta.env.VITE_SUPABASE_URL, 
import.meta.env.VITE_SUPABASE_ANON);

const supabase = () => client;

export default supabase;

Now, imports the supabase file in the login component

import supabase from "../supabase"

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
let { data, error } = await 
supabase().auth.signInWithPassword({ email, password })
if (error) {
  console.log(error.message)
} else {
  console.log(data)
}
}

I hope this help you

Upvotes: 0

user3405031
user3405031

Reputation: 1

Turning the "createBrowserClient" into a singleton fixed it for me (but don't do that for the serverClient).

Upvotes: 0

maaajo
maaajo

Reputation: 1035

The reason why I was getting this error is because I had to downgrade the auth-helpers-nextjs from 0.7.x to 0.6.x to support no email confirmation when registering,

Version 0.7.x automatically returns singleton object for createPagesBrowserClient

With version 0.6.x createBrowserSupabaseClient always return new object rather then singleton,

With reactStrictMode enabled with react 18 the page will render twice, causing the error of Multiple GoTrueClients.

How I fixed it is by creating a new object with singleton instance of Supabase Client:

import { createBrowserSupabaseClient } from "@supabase/auth-helpers-nextjs";

const SupabaseClient = {
  instance: createBrowserSupabaseClient(),
};

export type SupabaseClientType = typeof SupabaseClient;

Object.freeze(SupabaseClient);

export { SupabaseClient };

And then consume it in the _app.tsx:

const [supabaseClient] = useState(() => SupabaseClient.instance);

Now the warning should be gone.

Upvotes: 4

Donald Boulton
Donald Boulton

Reputation: 31

Better yet with typescript and auth headers

import { createClient } from "@supabase/supabase-js";
import { Database } from "@lib/database.types";

const options = {
  auth: {
    localStorage: true,
    autoRefreshToken: true,
    persistSession: true,
    detectSessionInUrl: true,
  },
};

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

const client = createClient<Database>(supabaseUrl, supabaseKey, options);

const supabase = () => client;

export default supabase;

Upvotes: 0

Kirk Strobeck
Kirk Strobeck

Reputation: 18619

Only run createClient once, then return that instance on subsequent executions


Change your code from

import { createClient } from '@supabase/supabase-js';

const supabase = () => createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY);

export default supabase;

to

import { createClient } from '@supabase/supabase-js';

const client = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY);

const supabase = () => client;

export default supabase;

Upvotes: 5

Related Questions