Created
March 23, 2023 22:18
-
-
Save AWaselnuk/dfbeb54091130d366a02d85bc5f8db33 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { LoaderArgs } from "@remix-run/server-runtime"; | |
import { | |
Outlet, | |
useFetcher, | |
useLoaderData, | |
useRevalidator, | |
} from "@remix-run/react"; | |
import { useEffect, useState } from "react"; | |
import { json } from "@remix-run/server-runtime"; | |
import { supabaseServerClient } from "~/utils/server/supabase.server"; | |
import { supabaseBrowserClient } from "~/utils/client/supabase"; | |
import type { User, SupabaseClient, Session } from "@supabase/supabase-js"; | |
export const loader = async ({ request }: LoaderArgs) => { | |
// We can retrieve the session on the server and hand it to the client. | |
// This is used to make sure the session is available immediately upon rendering | |
console.log("RUNNING APP LOADER"); | |
const response = new Response(); | |
const supabase = supabaseServerClient(request, response); | |
const { | |
data: { session }, | |
} = await supabase.auth.getSession(); | |
console.log("SESSION", session); | |
const user = session?.user; | |
// in order for the set-cookie header to be set, | |
// headers must be returned as part of the loader response | |
return json( | |
{ | |
session, | |
user, | |
}, | |
{ | |
headers: response.headers, | |
} | |
); | |
}; | |
export interface AppContext { | |
supabase: SupabaseClient; | |
user: User | null; | |
session: Session | null; | |
} | |
// Contains any page that needs access to auth or supabase client | |
export default function AppLayout() { | |
const { session: serverSession, user } = useLoaderData<typeof loader>(); | |
console.log("from loader", serverSession); // THIS IS STALE! | |
const fetcher = useFetcher(); | |
const revalidator = useRevalidator(); | |
// it is important to create a single instance of Supabase | |
// to use across client components - outlet context 👇 | |
const [supabase] = useState(() => supabaseBrowserClient()); | |
useEffect(() => { | |
const serverAccessToken = serverSession?.access_token; | |
const { | |
data: { subscription }, | |
} = supabase.auth.onAuthStateChange((event, session) => { | |
console.log("Auth change happening"); | |
console.log("client token", session?.access_token.slice(0, 5)); | |
console.log("server token", serverAccessToken?.slice(0, 5)); | |
if (session?.access_token !== serverAccessToken) { | |
console.log("Access token changed, revalidating"); | |
// The server token continues to be undefined which starts an infinite loop. | |
debugger; | |
revalidator.revalidate(); | |
} | |
}); | |
return () => { | |
subscription.unsubscribe(); | |
}; | |
}, [supabase, revalidator, serverSession]); | |
return ( | |
<> | |
<Outlet context={{ supabase, session: serverSession, user }} /> | |
</> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment