Created
March 21, 2022 12:55
-
-
Save zackdotcomputer/278344333895d8ef452cff24750f2d66 to your computer and use it in GitHub Desktop.
Fix Clerk Unmount on Reauth
This file contains 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 { AuthProvider, useAuth } from "@redwoodjs/auth"; | |
import { ClerkProvider, useClerk, useUser as useClerkUser } from "@clerk/clerk-react"; | |
import { FatalErrorBoundary, RedwoodProvider } from "@redwoodjs/web"; | |
import { RedwoodApolloProvider } from "@redwoodjs/web/apollo"; | |
import FatalErrorPage from "src/pages/FatalErrorPage"; | |
import Routes from "src/Routes"; | |
import "./index.css"; | |
import { navigate } from "@redwoodjs/router"; | |
import { PropsWithChildren, useEffect, useState } from "react"; | |
/** BEGIN Clerk Auth Setup */ | |
// Replace Redwood's <AuthProvider> with the <ClerkAuthProvider>. | |
// | |
// You can set user roles in a "roles" array on the public metadata in Clerk. | |
// | |
// Also, you need to add two env variables: CLERK_FRONTEND_API_URL for web and | |
// CLERK_API_KEY for api, with the frontend api host and api key, respectively, | |
// both from your Clerk.dev dashboard. | |
// | |
// Lastly, be sure to add the key "CLERK_FRONTEND_API_URL" in your app's redwood.toml | |
// [web] config "includeEnvironmentVariables" setting. | |
// This component holds off rendering its children until the clerk client has loaded once. | |
const ClerkAuthConsumer = ({ children }: PropsWithChildren<unknown>) => { | |
const clerk = useClerk(); | |
const [hasFirstLoaded, setHasFirstLoaded] = useState(false); | |
useEffect(() => { | |
if (clerk.client) { | |
setHasFirstLoaded(true); | |
} | |
}, [clerk.client]); | |
if (!hasFirstLoaded) { | |
return null; | |
} | |
return <>{children}</>; | |
}; | |
// This component triggers a reauth at the Redwood level whenever Clerk's auth state changes. | |
const ClerkAuthListener = ({ children }: PropsWithChildren<unknown>) => { | |
const { isSignedIn, user } = useClerkUser(); | |
const { reauthenticate } = useAuth(); | |
useEffect(() => { | |
reauthenticate(); | |
}, [isSignedIn, user, reauthenticate]); | |
return <>{children}</>; | |
}; | |
const ClerkAuthProvider = ({ children }) => { | |
const frontendApi = process.env.CLERK_FRONTEND_API_URL; | |
if (!frontendApi) { | |
throw new Error("Need to define env variable CLERK_FRONTEND_API_URL"); | |
} | |
return ( | |
<ClerkProvider frontendApi={frontendApi} navigate={(to) => navigate(to)}> | |
<ClerkAuthConsumer> | |
<AuthProvider type="clerk"> | |
<ClerkAuthListener>{children}</ClerkAuthListener> | |
</AuthProvider> | |
</ClerkAuthConsumer> | |
</ClerkProvider> | |
); | |
}; | |
/** END Clerk Auth Setup */ | |
const App = () => ( | |
<FatalErrorBoundary page={FatalErrorPage}> | |
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle"> | |
<ClerkAuthProvider> | |
<RedwoodApolloProvider> | |
<Routes /> | |
</RedwoodApolloProvider> | |
</ClerkAuthProvider> | |
</RedwoodProvider> | |
</FatalErrorBoundary> | |
); | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment