Docs / Switch from Google

Switch from Google to signo: Better Auth

Tested on 20 Oct 2026 with Better Auth 1.7.12 against a running signo. A new person signed up and signed in, and a person who had signed up with Google kept their account, with no extra settings.

The examples use login.example.com for signo and example.com for your site.

1. Register your site with signo

On the public signo, sign in at https://usesigno.co.uk/account/sites and add your site with the redirect URI below. The page shows the issuer (https://usesigno.co.uk), a client ID and a client secret.

On your own signo, run this on its server instead:

docker compose exec signo signo clients add --name "Example" --redirect-uri https://example.com/api/auth/callback/signo

It prints the issuer, a client ID and a client secret. Better Auth's callback is <baseURL>/api/auth/callback/<providerId>.

2. Replace the Google provider

On the server, swap the Google social provider for the Generic OAuth plugin:

 import { betterAuth } from "better-auth"
+import { genericOAuth } from "better-auth/plugins"

 export const auth = betterAuth({
-  socialProviders: {
-    google: {
-      clientId: process.env.GOOGLE_CLIENT_ID!,
-      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
-    },
-  },
+  plugins: [
+    genericOAuth({
+      config: [
+        {
+          providerId: "signo",
+          discoveryUrl: `${process.env.SIGNO_ISSUER}/.well-known/openid-configuration`,
+          clientId: process.env.SIGNO_CLIENT_ID!,
+          clientSecret: process.env.SIGNO_CLIENT_SECRET!,
+          scopes: ["openid", "email", "profile"],
+        },
+      ],
+    }),
+  ],
 })

In .env:

-GOOGLE_CLIENT_ID=...
-GOOGLE_CLIENT_SECRET=...
+SIGNO_ISSUER=https://login.example.com
+SIGNO_CLIENT_ID=<client id>
+SIGNO_CLIENT_SECRET=<client secret>

In the browser, the sign-in call names the new provider:

-await authClient.signIn.social({ provider: "google" })
+await authClient.signIn.social({ provider: "signo" })

Better Auth 1.7 treats Generic OAuth providers like built-in social providers, uses PKCE by default and checks signo's ID tokens against its published keys. Older Better Auth versions use authClient.signIn.oauth2({ providerId: "signo" }) and a different callback path; follow the Generic OAuth docs for your version.

3. Keep the people who signed up with Google

Nothing to do. Better Auth attaches a sign-in to the existing user with the same email when the new sign-in's email is verified and the existing account's email is verified too. signo's emails are always verified, and accounts created through Google are marked verified, so these people keep their account. In the test, the person who signed up with Google landed on the same user ID.

Accounts that were never verified, such as password sign-ups that skipped email confirmation, are not linked automatically; that is Better Auth's requireLocalEmailVerified default.