[GH-ISSUE #2243] OneTap google signin error #9112

Closed
opened 2026-04-13 04:27:07 -05:00 by GiteaMirror · 43 comments
Owner

Originally created by @coderrshyam on GitHub (Apr 13, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/2243

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  • Create a next.js app add setup better-auth
  • add oneTap option in auth.ts and oneTapCleint in auth-client.ts
  • create a /login page and under useEffect add await authClient.oneTap

Code:
//auth-client.ts

 oneTapClient({
      clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID as string,
      // Optional client configuration:
      autoSelect: false,
      cancelOnTapOutside: true,
      context: "signin",
      additionalOptions: {
        // Any extra options for the Google initialize method
      },
      // Configure prompt behavior and exponential backoff:
      promptOptions: {
        baseDelay: 1000, // Base delay in ms (default: 1000)
        maxAttempts: 5, // Maximum number of attempts before triggering onPromptNotification (default: 5)
      },
    }),

// login.tsx

useEffect(() => {
    const initializeOneTap = async () => {
      await autclient.oneTap();
    };
    initializeOneTap();
  }, []);

Current vs. Expected behavior

The user should signIn after clicking this but after clicking i got some errors:

The fetch of the id assertion endpoint resulted in a network error: ERR_FAILED
 Server did not send the correct CORS headers
[GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token.
The request has been aborted.Understand this error
[GSI_LOGGER]: FedCM get() rejects with AbortError: signal is aborted without reason

Image

Image

What version of Better Auth are you using?

1.2.6

Provide environment information

- OS -> Windows
- Browser -> Chrome
- Next.js -> 15.3.0

Which area(s) are affected? (Select all that apply)

Client

Auth config (if applicable)

import { betterAuth, type BetterAuthOptions } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { admin, emailOTP, oneTap } from "better-auth/plugins";
import { sendEmail } from "./actions/email";
import prisma from "./lib/prisma";


export const auth = betterAuth({
  baseURL: process.env.BETTER_AUTH_URL,
  basePath: "/api/auth",
  secret: process.env.BETTER_AUTH_SECRET,
  database: prismaAdapter(prisma, {
    provider: "postgresql",
  }),
  plugins: [
    admin(),
    emailOTP({
      sendVerificationOnSignUp: true,
      disableSignUp: false,
      expiresIn: 60 * 10, // 10 minutes
      async sendVerificationOTP({ email, otp, type }) {
        await sendEmail({ to: email, type, otp });
      },
    }),
    oneTap(),
  ],
  session: {
    expiresIn: 60 * 60 * 24 * 7, // 7 days
    updateAge: 60 * 60 * 24, // 1 day (every 1 day the session expiration is updated)
    cookieCache: {
      enabled: true,
      maxAge: 5 * 60, // 300 seconds (5 minutes)
    },
  },
  account: {
    accountLinking: {
      enabled: true,
      trustedProviders: ["google", "github"],
    },
  },
  emailAndPassword: {
    enabled: true,
    autoSignIn: false,
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
    github: {
      clientId: process.env.GITHUB_CLIENT_ID as string,
      clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
    },
  },
  rateLimit: {
    enabled: true,
    window: 15,
    max: 15,
    storage: "database",
    modelName: "rateLimit",
  },
} satisfies BetterAuthOptions);

export type Session = typeof auth.$Infer.Session;

Additional context

Fix error.

Originally created by @coderrshyam on GitHub (Apr 13, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/2243 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce - Create a next.js app add setup better-auth - add oneTap option in auth.ts and oneTapCleint in auth-client.ts - create a /login page and under useEffect add `await authClient.oneTap` Code: //auth-client.ts ```ts oneTapClient({ clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID as string, // Optional client configuration: autoSelect: false, cancelOnTapOutside: true, context: "signin", additionalOptions: { // Any extra options for the Google initialize method }, // Configure prompt behavior and exponential backoff: promptOptions: { baseDelay: 1000, // Base delay in ms (default: 1000) maxAttempts: 5, // Maximum number of attempts before triggering onPromptNotification (default: 5) }, }), ``` // login.tsx ```ts useEffect(() => { const initializeOneTap = async () => { await autclient.oneTap(); }; initializeOneTap(); }, []); ``` ### Current vs. Expected behavior The user should signIn after clicking this but after clicking i got some errors: ``` The fetch of the id assertion endpoint resulted in a network error: ERR_FAILED Server did not send the correct CORS headers [GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token. The request has been aborted.Understand this error [GSI_LOGGER]: FedCM get() rejects with AbortError: signal is aborted without reason ``` ![Image](https://github.com/user-attachments/assets/49f93eea-05df-40d4-90f1-424f176ffc60) ![Image](https://github.com/user-attachments/assets/363d8dff-2b84-44d3-a44f-e7b348b42e49) ### What version of Better Auth are you using? 1.2.6 ### Provide environment information ```bash - OS -> Windows - Browser -> Chrome - Next.js -> 15.3.0 ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth, type BetterAuthOptions } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import { admin, emailOTP, oneTap } from "better-auth/plugins"; import { sendEmail } from "./actions/email"; import prisma from "./lib/prisma"; export const auth = betterAuth({ baseURL: process.env.BETTER_AUTH_URL, basePath: "/api/auth", secret: process.env.BETTER_AUTH_SECRET, database: prismaAdapter(prisma, { provider: "postgresql", }), plugins: [ admin(), emailOTP({ sendVerificationOnSignUp: true, disableSignUp: false, expiresIn: 60 * 10, // 10 minutes async sendVerificationOTP({ email, otp, type }) { await sendEmail({ to: email, type, otp }); }, }), oneTap(), ], session: { expiresIn: 60 * 60 * 24 * 7, // 7 days updateAge: 60 * 60 * 24, // 1 day (every 1 day the session expiration is updated) cookieCache: { enabled: true, maxAge: 5 * 60, // 300 seconds (5 minutes) }, }, account: { accountLinking: { enabled: true, trustedProviders: ["google", "github"], }, }, emailAndPassword: { enabled: true, autoSignIn: false, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }, github: { clientId: process.env.GITHUB_CLIENT_ID as string, clientSecret: process.env.GITHUB_CLIENT_SECRET as string, }, }, rateLimit: { enabled: true, window: 15, max: 15, storage: "database", modelName: "rateLimit", }, } satisfies BetterAuthOptions); export type Session = typeof auth.$Infer.Session; ``` ### Additional context Fix error.
GiteaMirror added the locked label 2026-04-13 04:27:07 -05:00
Author
Owner

@ph8nt0m commented on GitHub (Apr 20, 2025):

@coderrshyam Did you solved? I have same problem.

<!-- gh-comment-id:2817204426 --> @ph8nt0m commented on GitHub (Apr 20, 2025): @coderrshyam Did you solved? I have same problem.
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

@coderrshyam Did you solved? I have same problem.

No bro, I am still facing this issue.
I am waiting for better-auth response.

<!-- gh-comment-id:2817207465 --> @coderrshyam commented on GitHub (Apr 20, 2025): > [@coderrshyam](https://github.com/coderrshyam) Did you solved? I have same problem. No bro, I am still facing this issue. I am waiting for better-auth response.
Author
Owner

@ph8nt0m commented on GitHub (Apr 20, 2025):

@coderrshyam try to add this

Google Console => Allowed JavaScript origins

Image
<!-- gh-comment-id:2817209636 --> @ph8nt0m commented on GitHub (Apr 20, 2025): @coderrshyam try to add this Google Console => Allowed JavaScript origins <img width="515" alt="Image" src="https://github.com/user-attachments/assets/5429bc1a-0346-4f67-a8f9-29dd14a5ae06" />
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

Let me clear one dought, Is the GOOGLE_CLIENT_ID is same for both Google one Tap and Google SignIn or not.

<!-- gh-comment-id:2817226611 --> @coderrshyam commented on GitHub (Apr 20, 2025): Let me clear one dought, Is the `GOOGLE_CLIENT_ID` is same for both `Google one Tap` and `Google SignIn` or not.
Author
Owner

@ph8nt0m commented on GitHub (Apr 20, 2025):

@coderrshyam It's same

I solved this issue by adding Allowed JavaScript origins

http://localhost and http://localhost:4000

also I add this

async headers() {
        return [
          {
            source: '/:path*',
            headers: [
              {
                key: 'Referrer-Policy',
                value: 'no-referrer-when-downgrade',
              },
            ],
          },
        ];
      },
<!-- gh-comment-id:2817227230 --> @ph8nt0m commented on GitHub (Apr 20, 2025): @coderrshyam It's same I solved this issue by adding Allowed JavaScript origins http://localhost and http://localhost:4000 also I add this ``` async headers() { return [ { source: '/:path*', headers: [ { key: 'Referrer-Policy', value: 'no-referrer-when-downgrade', }, ], }, ]; }, ```
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

where you add the following provided code

@coderrshyam It's same

I solved this issue by adding Allowed JavaScript origins

http://localhost and http://localhost:4000

also I add this

async headers() {
        return [
          {
            source: '/:path*',
            headers: [
              {
                key: 'Referrer-Policy',
                value: 'no-referrer-when-downgrade',
              },
            ],
          },
        ];
      },

where you add the provided code

<!-- gh-comment-id:2817232118 --> @coderrshyam commented on GitHub (Apr 20, 2025): where you add the following provided code > [@coderrshyam](https://github.com/coderrshyam) It's same > > I solved this issue by adding Allowed JavaScript origins > > http://localhost and http://localhost:4000 > > also I add this > > ``` > async headers() { > return [ > { > source: '/:path*', > headers: [ > { > key: 'Referrer-Policy', > value: 'no-referrer-when-downgrade', > }, > ], > }, > ]; > }, > ``` where you add the provided code
Author
Owner

@ph8nt0m commented on GitHub (Apr 20, 2025):

At next.config.ts

<!-- gh-comment-id:2817232440 --> @ph8nt0m commented on GitHub (Apr 20, 2025): At next.config.ts
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

What does your provide code do. is your provided code effect on security ??
Can you provide me documentation link for your code either next.js or better-auth

<!-- gh-comment-id:2817233745 --> @coderrshyam commented on GitHub (Apr 20, 2025): What does your provide code do. is your provided code effect on security ?? Can you provide me documentation link for your code either next.js or better-auth
Author
Owner

@ph8nt0m commented on GitHub (Apr 20, 2025):

Look at this document.

Provided code is only for test.

https://developers.google.com/identity/sign-in/web/gsi-with-fedcm?hl=ko

<!-- gh-comment-id:2817234546 --> @ph8nt0m commented on GitHub (Apr 20, 2025): Look at this document. Provided code is only for test. https://developers.google.com/identity/sign-in/web/gsi-with-fedcm?hl=ko
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

Ooo! It means i remove your provided code in deployement time ??

<!-- gh-comment-id:2817236558 --> @coderrshyam commented on GitHub (Apr 20, 2025): Ooo! It means i remove your provided code in deployement time ??
Author
Owner

@ph8nt0m commented on GitHub (Apr 20, 2025):

Look that document.

Only for using on development.

<!-- gh-comment-id:2817237064 --> @ph8nt0m commented on GitHub (Apr 20, 2025): Look that document. Only for using on development.
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

so, the code looks like:

 async headers() {
    return process.env.NODE_ENV !== "production"
      ? [
          {
            source: "/:path*",
            headers: [
              {
                key: "Referrer-Policy",
                value: "no-referrer-when-downgrade",
              },
            ],
          },
        ]
      : [];
  },
<!-- gh-comment-id:2817238341 --> @coderrshyam commented on GitHub (Apr 20, 2025): so, the code looks like: ```ts async headers() { return process.env.NODE_ENV !== "production" ? [ { source: "/:path*", headers: [ { key: "Referrer-Policy", value: "no-referrer-when-downgrade", }, ], }, ] : []; }, ```
Author
Owner

@ph8nt0m commented on GitHub (Apr 20, 2025):

@coderrshyam yes

<!-- gh-comment-id:2817238618 --> @ph8nt0m commented on GitHub (Apr 20, 2025): @coderrshyam yes
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

Thanks @ph8nt0m !

<!-- gh-comment-id:2817239269 --> @coderrshyam commented on GitHub (Apr 20, 2025): Thanks @ph8nt0m !
Author
Owner

@coderrshyam commented on GitHub (Apr 20, 2025):

I thinks that the solution is builtin come with better-auth

<!-- gh-comment-id:2817244330 --> @coderrshyam commented on GitHub (Apr 20, 2025): I thinks that the solution is builtin come with better-auth
Author
Owner

@coderrshyam commented on GitHub (Apr 23, 2025):

@coderrshyam It's same

I solved this issue by adding Allowed JavaScript origins

http://localhost and http://localhost:4000

also I add this

async headers() {
        return [
          {
            source: '/:path*',
            headers: [
              {
                key: 'Referrer-Policy',
                value: 'no-referrer-when-downgrade',
              },
            ],
          },
        ];
      },

Instead of modifying next.config.ts and apply headers to all path we can do like that

await oneTap({
      fetchOptions: {
        headers: {
          "Referrer-Policy": "no-referrer-when-downgrade",
        },
    });
<!-- gh-comment-id:2824506481 --> @coderrshyam commented on GitHub (Apr 23, 2025): > [@coderrshyam](https://github.com/coderrshyam) It's same > > I solved this issue by adding Allowed JavaScript origins > > http://localhost and http://localhost:4000 > > also I add this > > ``` > async headers() { > return [ > { > source: '/:path*', > headers: [ > { > key: 'Referrer-Policy', > value: 'no-referrer-when-downgrade', > }, > ], > }, > ]; > }, > ``` Instead of modifying `next.config.ts` and apply headers to all path we can do like that ```ts await oneTap({ fetchOptions: { headers: { "Referrer-Policy": "no-referrer-when-downgrade", }, }); ```
Author
Owner

@Bekacru commented on GitHub (May 7, 2025):

Seems like this is solved. Feel free to re-open if not.

<!-- gh-comment-id:2860625270 --> @Bekacru commented on GitHub (May 7, 2025): Seems like this is solved. Feel free to re-open if not.
Author
Owner

@coderrshyam commented on GitHub (May 8, 2025):

Seems like this is solved. Feel free to re-open if not.

Yep! This should be metioned in docs for google one tap headers: { "Referrer-Policy": "no-referrer-when-downgrade", },

<!-- gh-comment-id:2862392339 --> @coderrshyam commented on GitHub (May 8, 2025): > Seems like this is solved. Feel free to re-open if not. Yep! This should be metioned in docs for google one tap `headers: { "Referrer-Policy": "no-referrer-when-downgrade", },`
Author
Owner

@dvirben123 commented on GitHub (Sep 15, 2025):

I am still getting this error

[GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token.

the code:
const result = await oneTap({
fetchOptions: {
headers: {
"Referrer-Policy": "no-referrer-when-downgrade",
},
},
context: "signin",
onPromptNotification: (notification) => {
console.log("One Tap prompt notification:", notification);
},
});

<!-- gh-comment-id:3293386013 --> @dvirben123 commented on GitHub (Sep 15, 2025): I am still getting this error [GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token. the code: const result = await oneTap({ fetchOptions: { headers: { "Referrer-Policy": "no-referrer-when-downgrade", }, }, context: "signin", onPromptNotification: (notification) => { console.log("One Tap prompt notification:", notification); }, });
Author
Owner

@Esseh12 commented on GitHub (Sep 29, 2025):

I tried using the fix mentioned above, did

I am still getting this error

Image [GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token.

the code: const result = await oneTap({ fetchOptions: { headers: { "Referrer-Policy": "no-referrer-when-downgrade", }, }, context: "signin", onPromptNotification: (notification) => { console.log("One Tap prompt notification:", notification); }, });

<!-- gh-comment-id:3344430520 --> @Esseh12 commented on GitHub (Sep 29, 2025): I tried using the fix mentioned above, did > I am still getting this error > > <img alt="Image" width="763" height="677" src="https://private-user-images.githubusercontent.com/5688418/489676859-23c59765-b603-4d04-9e76-2530ae3cc962.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTkxMDQ4NjIsIm5iZiI6MTc1OTEwNDU2MiwicGF0aCI6Ii81Njg4NDE4LzQ4OTY3Njg1OS0yM2M1OTc2NS1iNjAzLTRkMDQtOWU3Ni0yNTMwYWUzY2M5NjIucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDkyOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA5MjlUMDAwOTIyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NzI3ZWFlYjIyZmFiMGEyYmY0Y2Q3YzZmY2RmY2MxZGI3ODJjY2FhM2ZjMmMwMzQ0ZDQyYWEyMThjYmE0NjU4MSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.311UzczNhEahw7HbIwVYT8Lpu2nB7yKqL5ZtGPMK-Pk"> > [GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token. > > the code: const result = await oneTap({ fetchOptions: { headers: { "Referrer-Policy": "no-referrer-when-downgrade", }, }, context: "signin", onPromptNotification: (notification) => { console.log("One Tap prompt notification:", notification); }, });
Author
Owner

@Esseh12 commented on GitHub (Sep 29, 2025):

I tried using the same fix mentioned above did it work for you??

<!-- gh-comment-id:3344430828 --> @Esseh12 commented on GitHub (Sep 29, 2025): I tried using the same fix mentioned above did it work for you??
Author
Owner

@coderrshyam commented on GitHub (Sep 29, 2025):

@dvirben123 and @Esseh12 can you share your auth-config, auth-client along with next-config code. Make sure to give your code in proper code block.

<!-- gh-comment-id:3344636933 --> @coderrshyam commented on GitHub (Sep 29, 2025): @dvirben123 and @Esseh12 can you share your auth-config, auth-client along with next-config code. Make sure to give your code in proper code block.
Author
Owner

@dvirben123 commented on GitHub (Sep 29, 2025):

Sure, here is my auth.ts

import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { admin, oneTap, emailOTP } from "better-auth/plugins";
import { db } from "@/models/db";
import { users, accounts, sessions, verificationTokens } from "@/models/schema";

export const auth = betterAuth({
  user: {
    additionalFields: {
      role: {
        type: "string",
        required: false,
        defaultValue: "user",
        input: false, // don't allow user to set role
      },
      lang: {
        type: "string",
        required: false,
        defaultValue: "he",
      },
    },
  },
  database: drizzleAdapter(db, {
    provider: "pg",

    schema: {
      user: users,
      account: accounts,
      session: sessions,
      verification: verificationTokens,
    },
  }),

  emailAndPassword: {
    enabled: true,
    autoLogin: true,
    loginAfterSignUp: true,
    requireEmailVerification: false, // Disable built-in verification since we'll use OTP
    async sendResetPassword({ user, url, token }) {
      console.log(`🔒 Sending password reset email to ${user.email}`);

      try {
        const { sendPasswordResetEmail } = await import("@/utils/email-service");
        const { getLocale } = await import("next-intl/server");

        const locale = await getLocale();
        const emailResult = await sendPasswordResetEmail({
          email: user.email,
          resetToken: token,
          resetUrl: url,
          locale,
          fullName: user.name || user.email,
        });

        if (emailResult.success) {
          console.log("✅ Password reset email sent successfully via Better Auth");
        } else {
          console.error("❌ Password reset email failed:", emailResult.error);
        }
      } catch (error) {
        console.error("❌ Error sending password reset email:", error);
      }
    },
  },

  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    },
    facebook: {
      clientId: process.env.FACEBOOK_APP_ID!,
      clientSecret: process.env.FACEBOOK_SECRET!,
    },
  },

  plugins: [
    admin({
      defaultRole: "user",
    }),
    oneTap()
  ],

  session: {
    expiresIn: 60 * 60 * 24 * 7, // 7 days
    updateAge: 60 * 60 * 24, // 7 days (don't update session frequently)
    cookieCache: {
      enabled: true,
      maxAge: 60 * 60 * 1, // 2 hours (increased cache duration)
    },
  },

  advanced: {
    cookiePrefix: "better-auth",
    uuid: true
  },

  trustedOrigins: [
    "http://localhost:3000",
    ...(process.env.NEXT_PUBLIC_APP_URL ? [process.env.NEXT_PUBLIC_APP_URL] : []),
    ...(process.env.BETTER_AUTH_URL ? [process.env.BETTER_AUTH_URL] : []),
  ],

  secret: process.env.BETTER_AUTH_SECRET,
  baseURL: (() => {
    // In development, use environment variable or detect from process.env.PORT
    if (process.env.NODE_ENV === 'development') {
      // Check for the actual Next.js dev server port
      const detectedPort = process.env.NEXT_DEV_PORT || process.env.PORT || "3000";
      const url = process.env.BETTER_AUTH_URL || `http://localhost:${detectedPort}`;
      return url;
    }

    const url = process.env.BETTER_AUTH_URL || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
    console.log("Better Auth server baseURL:", url);
    return url;
  })(),
});

export type Session = typeof auth.$Infer.Session;
export type User = typeof auth.$Infer.Session.user;

export type UserRole = "admin" | "user" | "therapist" | "guest"

The auth-client file :

"use client";

import { createAuthClient } from "better-auth/react";
import { oneTapClient, emailOTPClient } from "better-auth/client/plugins";

// Get the correct base URL for client-side auth
const getAuthBaseURL = () => {
  if (typeof window !== 'undefined') {
    // Client-side: use current window origin
    const baseURL = window.location.origin;
    console.log("Auth client base URL (client):", baseURL);
    return baseURL;
  }

  // Server-side: use environment variable with proper port detection
  const baseURL = process.env.BETTER_AUTH_URL || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
  console.log("Auth client base URL (server):", baseURL);
  return baseURL;
};

export const authClient = createAuthClient({
  baseURL: getAuthBaseURL(),
  fetchOptions: {
    timeout: 30000, // 30 second timeout
    onError: (context) => {
      console.error("Auth client fetch error:", {
        error: context.error,
        response: context.response,
        status: context.response?.status,
        headers: context.response?.headers
      });
    },
    onRequest: (context) => {
      console.log("Auth client making request to:", context.url);
    },
    onResponse: (context) => {
      console.log("Auth client response:", {
        status: context.response.status,
        ok: context.response.ok
      });
    }
  },
  plugins: [
    oneTapClient({
      clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID!,
      autoSelect: false,
      cancelOnTapOutside: true,
      context: "signin",
      promptOptions: {
        baseDelay: 1000,
        maxAttempts: 3
      }
    }),
    emailOTPClient()
  ]
});

// Export all the client-side auth methods
export const {
  signIn,
  signOut,
  signUp,
  useSession,
  getSession,
  updateUser,
  changeEmail,
  changePassword,
  sendVerificationEmail,
  resetPassword,
  forgetPassword,
  oneTap,
  listAccounts,
  verifyEmail,
  emailOtp,
} = authClient;

/**
 * Client-side auth helper function
 * Replaces NextAuth's useSession() hook with Better Auth
 */
export function useAuthSession() {
  return useSession();
}

/**
 * Social login helpers
 */
export const signInGoogle = async (callbackURL = "/") => {
  console.log("signInGoogle");
  const data = await signIn.social({
    provider: "google",
    callbackURL,
  });
  return data;
};

export const signInFacebook = async (callbackURL = "/") => {
  const data = await signIn.social({
    provider: "facebook",
    callbackURL,
  });
  return data;
};

/**
 * Email/Password login helper
 */
// Fallback auth function using direct fetch
const fallbackSignIn = async (email: string, password: string) => {
  try {
    const response = await fetch("/api/auth/sign-in", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ email, password }),
    });

    const data = await response.json();

    if (!response.ok) {
      return {
        error: data.message || "Authentication failed",
        ok: false
      };
    }

    return {
      ok: true,
      data
    };
  } catch (error) {
    console.error("Fallback sign in error:", error);
    return {
      error: error instanceof Error ? error.message : String(error),
      ok: false
    };
  }
};

export const signInEmail = async (email: string, password: string) => {
  try {
    console.log("Attempting to sign in with Better Auth...");
    const data = await signIn.email({
      email,
      password,
      callbackURL: "/",
    });
    console.log("Sign in response:", data);
    return data;
  } catch (error) {
    console.error("Better Auth sign in failed, trying fallback:", error);

    // If Better Auth fails, try fallback method
    if (error instanceof TypeError && error.message.includes("Failed to fetch")) {
      console.log("Using fallback auth method...");
      return await fallbackSignIn(email, password);
    }

    // Return error in expected format
    return {
      error: error instanceof Error ? error.message : String(error),
      ok: false
    };
  }
};

/**
 * Email/Password signup helper
 */
export const signUpEmail = async (email: string, password: string, name: string) => {
  try {
    console.log("Better Auth signup attempt:", { email, name });

    const data = await signUp.email({
      email,
      password,
      name,
      callbackURL: "/user/auth/verify",
    });

    console.log("Better Auth signup success:", data);
    return { data, ok: true };
  } catch (error) {
    console.error("Better Auth signup error:", error);

    // Handle specific error types
    if (error instanceof TypeError && error.message.includes("Failed to fetch")) {
      return {
        error: "Network error - please check your connection and try again",
        ok: false
      };
    }

    if (error instanceof Error && error.message.includes("timeout")) {
      return {
        error: "Request timed out - please try again",
        ok: false
      };
    }

    return {
      error: error instanceof Error ? error.message : String(error),
      ok: false
    };
  }
};

/**
 * Therapist signup helper
 */
export const signUpTherapist = async (email: string, password: string, name: string) => {
  return signUpEmail(email, password, name);
};

/**
 * Sign out helper
 */
export const signOutUser = async (options?: { callbackUrl?: string; redirect?: boolean }) => {
  await signOut();

  // Handle redirect manually if specified and redirect is not disabled
  if (options?.callbackUrl && options?.redirect !== false) {
    if (typeof window !== 'undefined') {
      window.location.href = options.callbackUrl;
    }
  }
};

/**
 * Get current session on client side
 */
export const getCurrentSession = async () => {
  try {
    const session = await getSession();
    return session;
  } catch (error) {
    console.error("Error getting session:", error);
    return null;
  }
};

/**
 * Google One Tap login helper
 */
export const triggerOneTap = async () => {
  try {
    console.log("Triggering Google One Tap...");
    const result = await oneTap({
      fetchOptions: {
        headers: {
          "Referrer-Policy": "no-referrer-when-downgrade",
        },
      },
      context: "signin",
      onPromptNotification: (notification) => {
        console.log("One Tap prompt notification:", notification);
      },
    });
    console.log("One Tap result:", result);
    return result;
  } catch (error) {
    console.error("One Tap error:", error);
    return {
      error: error instanceof Error ? error.message : String(error),
      ok: false
    };
  }
};

next.config.ts

import type { NextConfig } from "next";
import createNextIntlPlugin from "next-intl/plugin";

const withNextIntl = createNextIntlPlugin("./lib/i18n.ts");

const nextConfig: NextConfig = {
  productionBrowserSourceMaps: process.env.NODE_ENV === "production",
  crossOrigin: "anonymous",
  experimental: {
    optimizeCss: true,
    optimizeServerReact: true,
  },
  turbopack: {
    rules: {
      "*.svg": {
        loaders: ["@svgr/webpack"],
        as: "*.js",
      },
    },
  },
  pageExtensions: ["js", "jsx", "ts", "tsx", "mdx"],
  async headers() {
    return [
      {
        source: "/_next/static/:path*",
        headers: [
          {
            key: "Access-Control-Allow-Origin",
            value: "*",
          },
          {
            key: "Access-Control-Allow-Methods",
            value: "GET",
          },
        ],
      },
    ];
  },
  async rewrites() {
    return {
      beforeFiles: [
        ...(process.env.NODE_ENV === "production"
          ? [
            {
              source: "/studio/:path*",
              destination: "/404",
            },
            {
              source: "/[locale]/studio/:path*",
              destination: "/404",
            },
            {
              source: "/[locale]/(admin)/studio/:path*",
              destination: "/404",
            },
          ]
          : []),
      ],
    };
  },
  images: {
    qualities: [80, 85],
    remotePatterns: [
      {
        protocol: "https",
        hostname: "images.unsplash.com",
      },
   
      {
        protocol: "https",
        hostname: "img.youtube.com",
      },
    ],
  },
  eslint: {
    ignoreDuringBuilds: true,
  },
  typescript: {
    ignoreBuildErrors: true,
  },
};

export default withNextIntl(nextConfig);

@coderrshyam let me know if you need more info
thanks in advance

<!-- gh-comment-id:3345087827 --> @dvirben123 commented on GitHub (Sep 29, 2025): Sure, here is my **auth.ts** ``` import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { admin, oneTap, emailOTP } from "better-auth/plugins"; import { db } from "@/models/db"; import { users, accounts, sessions, verificationTokens } from "@/models/schema"; export const auth = betterAuth({ user: { additionalFields: { role: { type: "string", required: false, defaultValue: "user", input: false, // don't allow user to set role }, lang: { type: "string", required: false, defaultValue: "he", }, }, }, database: drizzleAdapter(db, { provider: "pg", schema: { user: users, account: accounts, session: sessions, verification: verificationTokens, }, }), emailAndPassword: { enabled: true, autoLogin: true, loginAfterSignUp: true, requireEmailVerification: false, // Disable built-in verification since we'll use OTP async sendResetPassword({ user, url, token }) { console.log(`🔒 Sending password reset email to ${user.email}`); try { const { sendPasswordResetEmail } = await import("@/utils/email-service"); const { getLocale } = await import("next-intl/server"); const locale = await getLocale(); const emailResult = await sendPasswordResetEmail({ email: user.email, resetToken: token, resetUrl: url, locale, fullName: user.name || user.email, }); if (emailResult.success) { console.log("✅ Password reset email sent successfully via Better Auth"); } else { console.error("❌ Password reset email failed:", emailResult.error); } } catch (error) { console.error("❌ Error sending password reset email:", error); } }, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, }, facebook: { clientId: process.env.FACEBOOK_APP_ID!, clientSecret: process.env.FACEBOOK_SECRET!, }, }, plugins: [ admin({ defaultRole: "user", }), oneTap() ], session: { expiresIn: 60 * 60 * 24 * 7, // 7 days updateAge: 60 * 60 * 24, // 7 days (don't update session frequently) cookieCache: { enabled: true, maxAge: 60 * 60 * 1, // 2 hours (increased cache duration) }, }, advanced: { cookiePrefix: "better-auth", uuid: true }, trustedOrigins: [ "http://localhost:3000", ...(process.env.NEXT_PUBLIC_APP_URL ? [process.env.NEXT_PUBLIC_APP_URL] : []), ...(process.env.BETTER_AUTH_URL ? [process.env.BETTER_AUTH_URL] : []), ], secret: process.env.BETTER_AUTH_SECRET, baseURL: (() => { // In development, use environment variable or detect from process.env.PORT if (process.env.NODE_ENV === 'development') { // Check for the actual Next.js dev server port const detectedPort = process.env.NEXT_DEV_PORT || process.env.PORT || "3000"; const url = process.env.BETTER_AUTH_URL || `http://localhost:${detectedPort}`; return url; } const url = process.env.BETTER_AUTH_URL || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000"; console.log("Better Auth server baseURL:", url); return url; })(), }); export type Session = typeof auth.$Infer.Session; export type User = typeof auth.$Infer.Session.user; export type UserRole = "admin" | "user" | "therapist" | "guest" ``` **The auth-client file :** ``` "use client"; import { createAuthClient } from "better-auth/react"; import { oneTapClient, emailOTPClient } from "better-auth/client/plugins"; // Get the correct base URL for client-side auth const getAuthBaseURL = () => { if (typeof window !== 'undefined') { // Client-side: use current window origin const baseURL = window.location.origin; console.log("Auth client base URL (client):", baseURL); return baseURL; } // Server-side: use environment variable with proper port detection const baseURL = process.env.BETTER_AUTH_URL || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000"; console.log("Auth client base URL (server):", baseURL); return baseURL; }; export const authClient = createAuthClient({ baseURL: getAuthBaseURL(), fetchOptions: { timeout: 30000, // 30 second timeout onError: (context) => { console.error("Auth client fetch error:", { error: context.error, response: context.response, status: context.response?.status, headers: context.response?.headers }); }, onRequest: (context) => { console.log("Auth client making request to:", context.url); }, onResponse: (context) => { console.log("Auth client response:", { status: context.response.status, ok: context.response.ok }); } }, plugins: [ oneTapClient({ clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID!, autoSelect: false, cancelOnTapOutside: true, context: "signin", promptOptions: { baseDelay: 1000, maxAttempts: 3 } }), emailOTPClient() ] }); // Export all the client-side auth methods export const { signIn, signOut, signUp, useSession, getSession, updateUser, changeEmail, changePassword, sendVerificationEmail, resetPassword, forgetPassword, oneTap, listAccounts, verifyEmail, emailOtp, } = authClient; /** * Client-side auth helper function * Replaces NextAuth's useSession() hook with Better Auth */ export function useAuthSession() { return useSession(); } /** * Social login helpers */ export const signInGoogle = async (callbackURL = "/") => { console.log("signInGoogle"); const data = await signIn.social({ provider: "google", callbackURL, }); return data; }; export const signInFacebook = async (callbackURL = "/") => { const data = await signIn.social({ provider: "facebook", callbackURL, }); return data; }; /** * Email/Password login helper */ // Fallback auth function using direct fetch const fallbackSignIn = async (email: string, password: string) => { try { const response = await fetch("/api/auth/sign-in", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email, password }), }); const data = await response.json(); if (!response.ok) { return { error: data.message || "Authentication failed", ok: false }; } return { ok: true, data }; } catch (error) { console.error("Fallback sign in error:", error); return { error: error instanceof Error ? error.message : String(error), ok: false }; } }; export const signInEmail = async (email: string, password: string) => { try { console.log("Attempting to sign in with Better Auth..."); const data = await signIn.email({ email, password, callbackURL: "/", }); console.log("Sign in response:", data); return data; } catch (error) { console.error("Better Auth sign in failed, trying fallback:", error); // If Better Auth fails, try fallback method if (error instanceof TypeError && error.message.includes("Failed to fetch")) { console.log("Using fallback auth method..."); return await fallbackSignIn(email, password); } // Return error in expected format return { error: error instanceof Error ? error.message : String(error), ok: false }; } }; /** * Email/Password signup helper */ export const signUpEmail = async (email: string, password: string, name: string) => { try { console.log("Better Auth signup attempt:", { email, name }); const data = await signUp.email({ email, password, name, callbackURL: "/user/auth/verify", }); console.log("Better Auth signup success:", data); return { data, ok: true }; } catch (error) { console.error("Better Auth signup error:", error); // Handle specific error types if (error instanceof TypeError && error.message.includes("Failed to fetch")) { return { error: "Network error - please check your connection and try again", ok: false }; } if (error instanceof Error && error.message.includes("timeout")) { return { error: "Request timed out - please try again", ok: false }; } return { error: error instanceof Error ? error.message : String(error), ok: false }; } }; /** * Therapist signup helper */ export const signUpTherapist = async (email: string, password: string, name: string) => { return signUpEmail(email, password, name); }; /** * Sign out helper */ export const signOutUser = async (options?: { callbackUrl?: string; redirect?: boolean }) => { await signOut(); // Handle redirect manually if specified and redirect is not disabled if (options?.callbackUrl && options?.redirect !== false) { if (typeof window !== 'undefined') { window.location.href = options.callbackUrl; } } }; /** * Get current session on client side */ export const getCurrentSession = async () => { try { const session = await getSession(); return session; } catch (error) { console.error("Error getting session:", error); return null; } }; /** * Google One Tap login helper */ export const triggerOneTap = async () => { try { console.log("Triggering Google One Tap..."); const result = await oneTap({ fetchOptions: { headers: { "Referrer-Policy": "no-referrer-when-downgrade", }, }, context: "signin", onPromptNotification: (notification) => { console.log("One Tap prompt notification:", notification); }, }); console.log("One Tap result:", result); return result; } catch (error) { console.error("One Tap error:", error); return { error: error instanceof Error ? error.message : String(error), ok: false }; } }; ``` **_next.config.ts_** ``` import type { NextConfig } from "next"; import createNextIntlPlugin from "next-intl/plugin"; const withNextIntl = createNextIntlPlugin("./lib/i18n.ts"); const nextConfig: NextConfig = { productionBrowserSourceMaps: process.env.NODE_ENV === "production", crossOrigin: "anonymous", experimental: { optimizeCss: true, optimizeServerReact: true, }, turbopack: { rules: { "*.svg": { loaders: ["@svgr/webpack"], as: "*.js", }, }, }, pageExtensions: ["js", "jsx", "ts", "tsx", "mdx"], async headers() { return [ { source: "/_next/static/:path*", headers: [ { key: "Access-Control-Allow-Origin", value: "*", }, { key: "Access-Control-Allow-Methods", value: "GET", }, ], }, ]; }, async rewrites() { return { beforeFiles: [ ...(process.env.NODE_ENV === "production" ? [ { source: "/studio/:path*", destination: "/404", }, { source: "/[locale]/studio/:path*", destination: "/404", }, { source: "/[locale]/(admin)/studio/:path*", destination: "/404", }, ] : []), ], }; }, images: { qualities: [80, 85], remotePatterns: [ { protocol: "https", hostname: "images.unsplash.com", }, { protocol: "https", hostname: "img.youtube.com", }, ], }, eslint: { ignoreDuringBuilds: true, }, typescript: { ignoreBuildErrors: true, }, }; export default withNextIntl(nextConfig); ``` @coderrshyam let me know if you need more info thanks in advance
Author
Owner

@coderrshyam commented on GitHub (Sep 29, 2025):

Quiet difficult to understand because you didn't use codeblocks. Let me repost it for better understanding and collaboration

<!-- gh-comment-id:3345095954 --> @coderrshyam commented on GitHub (Sep 29, 2025): Quiet difficult to understand because you didn't use codeblocks. Let me repost it for better understanding and collaboration
Author
Owner

@dvirben123 commented on GitHub (Sep 29, 2025):

Quiet difficult to understand because you didn't use codeblocks. Let me repost it for better understanding and collaboration

fix it

<!-- gh-comment-id:3345111285 --> @dvirben123 commented on GitHub (Sep 29, 2025): > Quiet difficult to understand because you didn't use codeblocks. Let me repost it for better understanding and collaboration fix it
Author
Owner

@coderrshyam commented on GitHub (Sep 29, 2025):

@dvirben123 can you try by adding the following line in your next.config.ts.

 async headers() {
    return process.env.NODE_ENV !== "production"
      ? [
          {
            source: "/:path*",
            headers: [
              {
                key: "Referrer-Policy",
                value: "no-referrer-when-downgrade",
              },
            ],
          },
        ]
      : [];
  },

And for now just remove your own headers code from next config i.e.:

// Remove it and add the provided code.

async headers() {
    return [
      {
        source: "/_next/static/:path*",
        headers: [
          {
            key: "Access-Control-Allow-Origin",
            value: "*",
          },
          {
            key: "Access-Control-Allow-Methods",
            value: "GET",
          },
        ],
      },
    ];
  },
<!-- gh-comment-id:3345172983 --> @coderrshyam commented on GitHub (Sep 29, 2025): @dvirben123 can you try by adding the following line in your `next.config.ts`. ```ts async headers() { return process.env.NODE_ENV !== "production" ? [ { source: "/:path*", headers: [ { key: "Referrer-Policy", value: "no-referrer-when-downgrade", }, ], }, ] : []; }, ``` And for now just remove your own headers code from next config i.e.: ```ts // Remove it and add the provided code. async headers() { return [ { source: "/_next/static/:path*", headers: [ { key: "Access-Control-Allow-Origin", value: "*", }, { key: "Access-Control-Allow-Methods", value: "GET", }, ], }, ]; }, ```
Author
Owner

@dvirben123 commented on GitHub (Sep 29, 2025):

Image

[GSI_LOGGER]: Your client application uses one of the Google One Tap prompt UI status methods that may stop functioning when FedCM becomes mandatory. Refer to the migration guide to update your code accordingly and opt-in to FedCM to test your changes. Learn more: https://developers.google.com/identity/gsi/web/guides/fedcm-migration?s=dc#display_moment and https://developers.google.com/identity/gsi/web/guides/fedcm-migration?s=dc&utm_source=devtools&utm_campaign=stable#skipped_moment

I am also getting this error :
[GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token.

<!-- gh-comment-id:3345218609 --> @dvirben123 commented on GitHub (Sep 29, 2025): <img width="372" height="167" alt="Image" src="https://github.com/user-attachments/assets/5f00a421-95f0-462a-a1ae-783d20142416" /> [GSI_LOGGER]: Your client application uses one of the Google One Tap prompt UI status methods that may stop functioning when FedCM becomes mandatory. Refer to the migration guide to update your code accordingly and opt-in to FedCM to test your changes. Learn more: https://developers.google.com/identity/gsi/web/guides/fedcm-migration?s=dc#display_moment and https://developers.google.com/identity/gsi/web/guides/fedcm-migration?s=dc&utm_source=devtools&utm_campaign=stable#skipped_moment I am also getting this error : [GSI_LOGGER]: FedCM get() rejects with IdentityCredentialError: Error retrieving a token.
Author
Owner

@coderrshyam commented on GitHub (Sep 29, 2025):

It looks like some changes internal changes made, better-auth team can help you. You should create a new issue with refference to all logs and codes.

Also I am no longer using oneTap plugin due to performance issues.

<!-- gh-comment-id:3345262973 --> @coderrshyam commented on GitHub (Sep 29, 2025): It looks like some changes internal changes made, better-auth team can help you. You should create a new issue with refference to all logs and codes. Also I am no longer using oneTap plugin due to performance issues.
Author
Owner

@dvirben123 commented on GitHub (Sep 29, 2025):

@ping-maxwell can you have a look at the last comments and try helping us to solve this issue?

<!-- gh-comment-id:3345548367 --> @dvirben123 commented on GitHub (Sep 29, 2025): @ping-maxwell can you have a look at the last comments and try helping us to solve this issue?
Author
Owner

@dvirben123 commented on GitHub (Oct 5, 2025):

It looks like some changes internal changes made, better-auth team can help you. You should create a new issue with refference to all logs and codes.

Also I am no longer using oneTap plugin due to performance issues.

Can you reopen this issue ?

<!-- gh-comment-id:3369080588 --> @dvirben123 commented on GitHub (Oct 5, 2025): > It looks like some changes internal changes made, better-auth team can help you. You should create a new issue with refference to all logs and codes. > > Also I am no longer using oneTap plugin due to performance issues. Can you reopen this issue ?
Author
Owner

@coderrshyam commented on GitHub (Oct 5, 2025):

I didn't have permission to open to this issue. Only owners/maintainers can open this

<!-- gh-comment-id:3369083990 --> @coderrshyam commented on GitHub (Oct 5, 2025): I didn't have permission to open to this issue. Only owners/maintainers can open this
Author
Owner

@mattshma commented on GitHub (Oct 23, 2025):

I also encountered the error in my development when I only set http://localhost:5173 in the Authorized JavaScript origins settings (Google Auth Platform).

After I add http://localhost the error was gone.

Reference:

Key Point: For local tests or development add both http://localhost and http://localhost:<port_number>.

<!-- gh-comment-id:3436515474 --> @mattshma commented on GitHub (Oct 23, 2025): I also encountered the error in my development when I only set `http://localhost:5173` in the **Authorized JavaScript origins** settings (Google Auth Platform). After I add `http://localhost` the error was gone. [Reference](https://developers.google.com/identity/sign-in/web/gsi-with-fedcm#setup): > Key Point: For local tests or development add both http://localhost and http://localhost:<port_number>.
Author
Owner

@huhan-123 commented on GitHub (Dec 17, 2025):

@coderrshyam try to add this

Google Console => Allowed JavaScript origins

Image

I succeeded using your method, thank you.

<!-- gh-comment-id:3664299532 --> @huhan-123 commented on GitHub (Dec 17, 2025): > [@coderrshyam](https://github.com/coderrshyam) try to add this > > Google Console => Allowed JavaScript origins > > <img alt="Image" width="515" src="https://private-user-images.githubusercontent.com/67618117/435476337-5429bc1a-0346-4f67-a8f9-29dd14a5ae06.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NjU5NjE2NDIsIm5iZiI6MTc2NTk2MTM0MiwicGF0aCI6Ii82NzYxODExNy80MzU0NzYzMzctNTQyOWJjMWEtMDM0Ni00ZjY3LWE4ZjktMjlkZDE0YTVhZTA2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTEyMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUxMjE3VDA4NDkwMlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTIwNTIzM2UzNjZjZDQ1NTkyMTFmNThlMjU0MmVkNzk4ZWFlZGNkMTAyZDc4MDlhNjlhYTJlMmRmYjI1Y2RiNjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.qanHRmDi2iIhpS03ihf9Z7pV7oPxC-V5iNeqIDvJekg"> I succeeded using your method, thank you.
Author
Owner

@gmqiyue commented on GitHub (Dec 27, 2025):

@coderrshyam try to add this

Google Console => Allowed JavaScript origins

Image

worked for me! thx

<!-- gh-comment-id:3693975804 --> @gmqiyue commented on GitHub (Dec 27, 2025): > [@coderrshyam](https://github.com/coderrshyam) try to add this > > Google Console => Allowed JavaScript origins > > <img alt="Image" width="515" src="https://private-user-images.githubusercontent.com/67618117/435476337-5429bc1a-0346-4f67-a8f9-29dd14a5ae06.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NjY4NDIwNjgsIm5iZiI6MTc2Njg0MTc2OCwicGF0aCI6Ii82NzYxODExNy80MzU0NzYzMzctNTQyOWJjMWEtMDM0Ni00ZjY3LWE4ZjktMjlkZDE0YTVhZTA2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTEyMjclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUxMjI3VDEzMjI0OFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYxODZjNDQ4ZGY5MDQ2MGY4MDk4NWE1M2FjZmMxZjQyMDU4ZjQ0NGZiMzU0OGRkOGQ5YTU1YjRlNmZjZGNkZjEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.H3d3TF3NfVkku5A2TlFItf-Y4aDAwI3yCbiLmFAvL4c"> worked for me! thx
Author
Owner

@SaurabhSonde commented on GitHub (Feb 2, 2026):

Is anyone able to solve this? I’m stuck and need help.

<!-- gh-comment-id:3836835415 --> @SaurabhSonde commented on GitHub (Feb 2, 2026): Is anyone able to solve this? I’m stuck and need help.
Author
Owner

@dvirben123 commented on GitHub (Feb 2, 2026):

The issue still occurs

<!-- gh-comment-id:3837310687 --> @dvirben123 commented on GitHub (Feb 2, 2026): The issue still occurs
Author
Owner

@SaurabhSonde commented on GitHub (Feb 2, 2026):

I’ve tried every possible approach, but the issue still persists. When I try to deploy the code, it throws a different error: ‘Required parameter is missing: response_type’. In local development, the FedCM authorization is getting blocked and throws a CORS error, even though all JavaScript origins are added in the Google Console, including versions with and without the port. I’ve tested this in Arc, where it works perfectly fine, but in Chrome it doesn’t. This is really frustrating.

<!-- gh-comment-id:3837326344 --> @SaurabhSonde commented on GitHub (Feb 2, 2026): I’ve tried every possible approach, but the issue still persists. When I try to deploy the code, it throws a different error: ‘Required parameter is missing: response_type’. In local development, the FedCM authorization is getting blocked and throws a CORS error, even though all JavaScript origins are added in the Google Console, including versions with and without the port. I’ve tested this in Arc, where it works perfectly fine, but in Chrome it doesn’t. This is really frustrating.
Author
Owner

@SaurabhSonde commented on GitHub (Feb 4, 2026):

Need help if anyone was able to solve this

<!-- gh-comment-id:3845969065 --> @SaurabhSonde commented on GitHub (Feb 4, 2026): Need help if anyone was able to solve this
Author
Owner

@coderrshyam commented on GitHub (Feb 4, 2026):

In my case, I solved this issue by the following ways:

  • Adding Allowed origins in Google console
  • By adding the following snippet in next.config.ts.
 async headers() {
    return process.env.NODE_ENV !== "production"
      ? [
          {
            source: "/:path*",
            headers: [
              {
                key: "Referrer-Policy",
                value: "no-referrer-when-downgrade",
              },
            ],
          },
        ]
      : [];
  },
<!-- gh-comment-id:3846058463 --> @coderrshyam commented on GitHub (Feb 4, 2026): In my case, I solved this issue by the following ways: - Adding Allowed origins in Google console - By adding the following snippet in `next.config.ts`. ```tsx async headers() { return process.env.NODE_ENV !== "production" ? [ { source: "/:path*", headers: [ { key: "Referrer-Policy", value: "no-referrer-when-downgrade", }, ], }, ] : []; }, ```
Author
Owner

@SaurabhSonde commented on GitHub (Feb 4, 2026):

This snippet will not work in production i am getting Required parameter is missing: response_type error in production and in local its the usual cors error

<!-- gh-comment-id:3846089606 --> @SaurabhSonde commented on GitHub (Feb 4, 2026): This snippet will not work in production i am getting Required parameter is missing: response_type error in production and in local its the usual cors error
Author
Owner

@Bartek532 commented on GitHub (Feb 8, 2026):

Hey, did anyone manage to solve this?

<!-- gh-comment-id:3867234206 --> @Bartek532 commented on GitHub (Feb 8, 2026): Hey, did anyone manage to solve this?
Author
Owner

@SaurabhSonde commented on GitHub (Feb 12, 2026):

Is it fix now with this pr

<!-- gh-comment-id:3890606384 --> @SaurabhSonde commented on GitHub (Feb 12, 2026): Is it fix now with this pr
Author
Owner

@coderrshyam commented on GitHub (Feb 12, 2026):

Take a try with npm i https://pkg.pr.new/better-auth/better-auth/@better-auth/core@7928

<!-- gh-comment-id:3890871846 --> @coderrshyam commented on GitHub (Feb 12, 2026): Take a try with `npm i https://pkg.pr.new/better-auth/better-auth/@better-auth/core@7928`
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9112