Skip to content

Instantly share code, notes, and snippets.

@AWaselnuk
Created March 23, 2023 22:18
Show Gist options
  • Save AWaselnuk/dfbeb54091130d366a02d85bc5f8db33 to your computer and use it in GitHub Desktop.
Save AWaselnuk/dfbeb54091130d366a02d85bc5f8db33 to your computer and use it in GitHub Desktop.
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