Skip to content

Sign In with One Tap

Google One Tap asks users who are signed in to Google whether to continue as that account, without leaving the page. The browser draws the prompt through its FedCM API, so how it looks depends on the browser. Like the button, it hands you an ID token: verify it on your server before you trust it.

Call useOneTap in a component. The prompt shows as soon as Google’s script has loaded:

<script setup lang="ts">
import { useOneTap, type CredentialResponse } from "vue3-google-signin";
useOneTap({
onSuccess: (response: CredentialResponse) => {
console.log("Success:", response);
},
onError: () => console.error("Error with One Tap Login"),
// options
});
</script>
<template>
<!-- nothing to render: Google shows its own One Tap prompt -->
</template>

When the component unmounts, the prompt closes.

Set disableAutomaticPrompt and call login() when you want the prompt:

<script setup lang="ts">
import { useOneTap, type CredentialResponse } from "vue3-google-signin";
const { isReady, login } = useOneTap({
disableAutomaticPrompt: true,
onSuccess: (response: CredentialResponse) => {
console.log("Success:", response);
},
onError: () => console.error("Error with One Tap Login"),
// options
});
</script>
<template>
<button :disabled="!isReady" @click="() => login()">
Sign in with One Tap
</button>
</template>

One Tap is meant for visitors who aren’t signed in to your app. Put it in a component and mount that component only while nobody is signed in. Once the user signs in, the component unmounts and the prompt goes away.

App.vue
<script setup lang="ts">
import GoogleOneTap from "./components/GoogleOneTap.vue";
import { useAuth } from "./auth"; // your auth state
const { user } = useAuth();
</script>
<template>
<GoogleOneTap v-if="!user" />
<RouterView />
</template>

With autoSelect: true, a returning user who has only one Google session that approved your app is signed in without a tap:

useOneTap({
autoSelect: true,
onSuccess: ({ credential }) => signIn(credential),
});

When they sign out, call window.google?.accounts.id.disableAutoSelect(), or One Tap signs them straight back in. See Sign users out.

context picks the title Google shows: "signin" (the default), "signup" or "use".

useOneTap({ context: "signup", onSuccess });

One Tap doesn’t always show. onPromptMomentNotification reports what happened:

useOneTap({
onSuccess,
onPromptMomentNotification: (notification) => {
if (notification.isSkippedMoment()) {
console.log("skipped:", notification.getSkippedReason());
}
if (notification.isDismissedMoment()) {
console.log("dismissed:", notification.getDismissedReason());
}
},
});

The usual reasons:

  • Cooldown. After a user closes the prompt, the browser waits before showing it again, longer each time. Google calls this the exponential cooldown. Clicking a button that calls login() doesn’t skip it.
  • Origin. The page’s origin, with its port, must be listed under Authorized JavaScript origins for your client ID.
  • No Google session. The user isn’t signed in to Google in this browser, or has turned off third-party sign-in prompts in the browser’s settings.

Because One Tap can always be skipped, keep a sign-in button on your login page too.