Google Sign-In
Google Sign-In provides a secure and convenient way for users to sign in to your app using their Google Account with One Tap, personalized buttons, and automatic sign-in.
Nuxt Scripts provides a registry script composable useScriptGoogleSignIn() to easily integrate Google Sign-In in your Nuxt app with optimal performance.
Nuxt Config Setup
The simplest way to load Google Sign-In globally in your Nuxt App is to use Nuxt config. Alternatively you can directly use the useScriptGoogleSignIn composable.
export default defineNuxtConfig({
scripts: {
registry: {
googleSignIn: {
clientId: '123456789.apps.googleusercontent.com'
}
}
}
})useScriptGoogleSignIn()
The useScriptGoogleSignIn composable lets you have fine-grain control over when and how Google Sign-In is loaded on your site.
const { proxy } = useScriptGoogleSignIn()
proxy.accounts.id.prompt()Please follow the Registry Scripts guide to learn more about advanced usage.
Live Demo
Sign in with your Google account:
Or
Moment Notifications
Track the One Tap display state:
const { onLoaded } = useScriptGoogleSignIn()
onLoaded(({ accounts }) => {
accounts.id.prompt((notification) => {
if (notification.isDisplayMoment()) {
if (notification.isDisplayed()) {
console.log('One Tap displayed')
}
else {
console.log('Not displayed:', notification.getNotDisplayedReason())
}
}
if (notification.isSkippedMoment()) {
console.log('Skipped:', notification.getSkippedReason())
}
if (notification.isDismissedMoment()) {
console.log('Dismissed:', notification.getDismissedReason())
}
})
})
Server-Side Verification
Always verify the credential token on your server:
export default defineEventHandler(async (event) => {
const { credential } = await readBody(event)
// Verify the token with Google
const response = await $fetch(`https://oauth2.googleapis.com/tokeninfo`, {
params: { id_token: credential }
})
// Verify the client ID matches
if (response.aud !== 'YOUR_CLIENT_ID') {
throw createError({ statusCode: 401, message: 'Invalid token' })
}
// Create session with user info
const user = {
email: response.email,
name: response.name,
picture: response.picture,
sub: response.sub
}
return { user }
})
FedCM API Support
Enable Privacy Sandbox FedCM API support for enhanced privacy. FedCM adoption becomes mandatory in August 2025.
export default defineNuxtConfig({
scripts: {
registry: {
googleSignIn: {
clientId: 'YOUR_CLIENT_ID',
useFedcmForPrompt: true
}
}
}
})
Cross-Origin Iframes
When using One Tap or the Sign-In button in cross-origin iframes with FedCM, add the allow attribute to all parent iframes:
<iframe src="https://your-app.com/login" allow="identity-credentials-get"></iframe>
prompt_parent_id is not supported.Revoking Access
Allow users to revoke access to their Google Account:
const { onLoaded } = useScriptGoogleSignIn()
function revokeAccess(userId: string) {
onLoaded(({ accounts }) => {
accounts.id.revoke(userId, (response) => {
if (response.successful) {
console.log('Access revoked')
}
else {
console.error('Revocation failed:', response.error)
}
})
})
}
Best Practices
Logout Handling
Always call disableAutoSelect() when the user signs out to prevent automatic re-authentication:
function signOut() {
// Clear your app's session
user.value = null
// Prevent One Tap from auto-selecting this account
onLoaded(({ accounts }) => {
accounts.id.disableAutoSelect()
})
}
Hosted Domain Restriction
Restrict sign-in to a specific Google Workspace domain:
accounts.id.initialize({
client_id: 'YOUR_CLIENT_ID',
callback: handleCredentialResponse,
hd: 'your-company.com' // Only allow users from this domain
})
Local Development Setup
To test Google Sign-In locally:
- Go to Google Cloud Console → Credentials
- Create or select an OAuth 2.0 Client ID (Web application type)
- Under Authorized JavaScript origins, add:
http://localhosthttp://localhost:3000(or your dev server port)
- Save and copy your Client ID
http://localhost (not 127.0.0.1) for local development. You don't need a redirect URI when using popup mode.Then configure your environment:
NUXT_PUBLIC_SCRIPTS_GOOGLE_SIGN_IN_CLIENT_ID=your-client-id.apps.googleusercontent.com
Guides
clientIdstring required Your Google API client ID.
autoSelectbooleanAuto-select credentials when only one Google account is available.
context'signin' | 'signup' | 'use'The context text for the One Tap prompt.
useFedcmForPromptbooleanEnable FedCM (Federated Credential Management) API support. Mandatory from August 2025.
cancelOnTapOutsideboolean = trueCancel the One Tap prompt if the user clicks outside.
uxMode'popup' | 'redirect'The UX mode for the sign-in flow.
loginUristringThe URI to redirect to after sign-in when using redirect UX mode.
itpSupportbooleanEnable Intelligent Tracking Prevention (ITP) support for Safari.
allowedParentOriginstring | string[]Allowed parent origin(s) for iframe embedding.
hdstringRestrict sign-in to a specific Google Workspace hosted domain.
Example
One Tap Sign-In
The One Tap prompt provides a simplified sign-in experience:
<script setup lang="ts">
const { onLoaded } = useScriptGoogleSignIn()
function handleCredentialResponse(response: CredentialResponse) {
// Send the credential to your backend for verification
await $fetch('/api/auth/google', {
method: 'POST',
body: { credential: response.credential }
})
}
onMounted(() => {
onLoaded(({ accounts }) => {
accounts.id.initialize({
client_id: 'YOUR_CLIENT_ID',
callback: handleCredentialResponse,
context: 'signin',
ux_mode: 'popup',
use_fedcm_for_prompt: true // Use Privacy Sandbox FedCM API
})
// Show One Tap
accounts.id.prompt()
})
})
</script>
Personalized Button
Render Google's personalized Sign in with Google button:
<script setup lang="ts">
const { onLoaded } = useScriptGoogleSignIn()
function handleCredentialResponse(response: CredentialResponse) {
console.log('Signed in!', response.credential)
}
onMounted(() => {
onLoaded(({ accounts }) => {
accounts.id.initialize({
client_id: 'YOUR_CLIENT_ID',
callback: handleCredentialResponse
})
const buttonDiv = document.getElementById('g-signin-button')
if (buttonDiv) {
accounts.id.renderButton(buttonDiv, {
type: 'standard',
theme: 'outline',
size: 'large',
text: 'signin_with',
shape: 'rectangular',
logo_alignment: 'left'
})
}
})
})
</script>
<template>
<div id="g-signin-button" />
</template>