---
title: One Tap
description: One Tap plugin for Better Auth
---

The One Tap plugin allows users to log in with a single tap using Google's One Tap API. The plugin
provides a simple way to integrate One Tap into your application, handling the client-side and server-side logic for you.

## Installation

### Add the Server Plugin

Add the One Tap plugin to your auth configuration:

```ts title="auth.ts"
import { betterAuth } from "better-auth";
import { oneTap } from "better-auth/plugins"; // [!code highlight]

export const auth = betterAuth({
    plugins: [ // [!code highlight]
        oneTap(), // Add the One Tap server plugin  // [!code highlight]
    ] // [!code highlight]
});
```

### Add the Client Plugin

Add the client plugin and specify where the user should be redirected after sign-in or if additional verification (like 2FA) is needed.


```ts
import { createAuthClient } from "better-auth/client";
import { oneTapClient } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  plugins: [
    oneTapClient({
      clientId: "YOUR_CLIENT_ID",
      // 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)
      }
    })
  ]
});
```

### Usage

To display the One Tap popup, simply call the oneTap method on your auth client:

```ts
await authClient.oneTap();
```

### Customizing Redirect Behavior

By default, after a successful login the plugin will hard redirect the user to `/`. You can customize this behavior as follows:

#### Avoiding a Hard Redirect

Pass fetchOptions with an onSuccess callback to handle the login response without a page reload:

```ts
await authClient.oneTap({
  fetchOptions: {
    onSuccess: () => {
      // For example, use a router to navigate without a full reload:
      router.push("/dashboard");
    }
  }
});
```

#### Specifying a Custom Callback URL

To perform a hard redirect to a different page after login, use the callbackURL option:

```ts
await authClient.oneTap({
  callbackURL: "/dashboard"
});
```

#### Handling Prompt Dismissals with Exponential Backoff

If the user dismisses or skips the prompt, the plugin will retry showing the One Tap prompt using exponential backoff based on your configured promptOptions.

If the maximum number of attempts is reached without a successful sign-in, you can use the onPromptNotification callback to be notified—allowing you to render an alternative UI (e.g., a traditional Google Sign-In button) so users can restart the process manually:

```ts
await authClient.oneTap({
  onPromptNotification: (notification) => {
    console.warn("Prompt was dismissed or skipped. Consider displaying an alternative sign-in option.", notification);
    // Render your alternative UI here
  }
});
```

### Client Options

- **clientId**: The client ID for your Google One Tap API.
- **autoSelect**: Automatically select the account if the user is already signed in. Default is false.
- **context**: The context in which the One Tap API should be used (e.g., "signin"). Default is "signin".
- **cancelOnTapOutside**: Cancel the One Tap popup when the user taps outside it. Default is true.
- additionalOptions: Extra options to pass to Google's initialize method as per the [Google Identity Services docs](https://developers.google.com/identity/gsi/web/reference/js-reference#google.accounts.id.prompt).
- **promptOptions**: Configuration for the prompt behavior and exponential backoff:
- **baseDelay**: Base delay in milliseconds for retries. Default is 1000.
- **maxAttempts**: Maximum number of prompt attempts before invoking the onPromptNotification callback. Default is 5.

### Server Options

- **disableSignUp**:  Disable the sign-up option, allowing only existing users to sign in. Default is `false`.
- **ClientId**: Optionally, pass a client ID here if it is not provided in your social provider configuration.

