%% generate tags start %% #software-engineering #software-engineering/authentication %% generate tags end %% #software-engineering/authentication/clerk #software-engineering/remix 1. go to clerk and set up a project 2. copy the secret to vercel, make sure update the `env.server.ts` 1. the publish key 2. the secret 3. the after sign in url 4. the after sign up url 3. then follow the documentation 4. make a `/sso-callback` page because we are not using the `/sign-in` and `sign-up` route which are the default. (if we are not doing default, clerk say we are doing the “custom” way) 5. in your local env, test if it is working, new user should be created in development env 6. push to preview to see if it is working 7. set the DNS in the cloudflare, make sure comment the DNS record with `<project> clerk required`, verify it. 8. enable google oauth provider, you need to go to google api console to set it up. 9. copy the production secret to vercel. see https://clerk.com/docs/deployments/overview?_gl=1*19fo871*_gcl_au*NDUzNjM5Nzc5LjE3MDQ5NzM1NDguNTIyNjg3MzUuMTcwNTA5ODcxNC4xNzA1MDk4NzEz*_ga*NTA3MTg1MTY0LjE3MDQ5NzM1NDg.*_ga_1WMF5X234K*MTcwNTEzOTU4NS42LjEuMTcwNTE0MDc2OC4wLjAuMA..#dns-records:~:text=A%20common%20mistake,provide%20your%20own. 10. push to production, test if working in production. new user should be created in production. > [!warning] clerk use have different prefix in env secret in production and development instance! ![](https://res.cloudinary.com/yomaru/image/upload/v1705141351/obsidian/mnhub6j5urjwa7bk5s9b.webp) ```tsx // root.tsx export async function loader(args: LoaderFunctionArgs) { // the loader must be written this way // I tried doing {... await rootAuthLoader(...)} and crash the app return rootAuthLoader(args, () => { return { // here put the data you want vercelEnv: process.env.VERCEL_ENV, }; }); } export const ErrorBoundary = ClerkErrorBoundary(); // ... export default ClerkApp(app) ``` ```tsx // sso-callback import { AuthenticateWithRedirectCallback } from "@clerk/remix"; export default function Page() { return <AuthenticateWithRedirectCallback />; } ``` ```tsx <SignIn routing={"path"} path={"/"} /> <SignedIn> you are signed in <SignOutButton> <Button>Signout</Button> </SignOutButton> </SignedIn> <SignedOut>you are signed out</SignedOut> ``` ![](https://res.cloudinary.com/yomaru/image/upload/v1705143277/obsidian/j7ob7c9rpk3szdzflehn.webp) ![](https://res.cloudinary.com/yomaru/image/upload/v1705142947/obsidian/ziwrdgz3z1dsfwuia94v.webp) ![](https://res.cloudinary.com/yomaru/image/upload/v1705140875/obsidian/h6c7ejnhzymoladcyvic.webp)