Skip to content

Instantly share code, notes, and snippets.

@srestraj
Last active December 13, 2023 04:50
Show Gist options
  • Save srestraj/c61d0a025f53ab7f99bd875eace5cc84 to your computer and use it in GitHub Desktop.
Save srestraj/c61d0a025f53ab7f99bd875eace5cc84 to your computer and use it in GitHub Desktop.
Integrate Google Sign-in and One-tap with Nuxt.js

Integrate Google Sign-in (Popup method) with Nuxt.js - Works in Incognito mode as well

Nuxt 3 version here.
Add GSI client in your nuxt.config.js
export default {
  ...
  head: {
    ...
    script: [
      {
        src: 'https://accounts.google.com/gsi/client',
      },
    ],
    ...
  }
  ...
}
In your login page or component, add the Google Button div (this will be populated by the rendered button)
<div id="googleButton"></div>
Inside your mounted hook, initialize the Google Sign in and render the Sign in button
<template>
  <div id="googleButton"></div>
</template>
<script>

export default {
  mounted() {
    // initialize Google Sign in  
    google.accounts.id.initialize({
        client_id: 'YOUR_CLIENT_ID',
        callback: this.handleCredentialResponse, //method to run after user clicks the Google sign in button
        context: 'signin'
      })
    
    // render button
    google.accounts.id.renderButton(
      document.getElementById('googleButton'),
      { 
        type: 'standard',
        size: 'large',
        text: 'signin_with',
        shape: 'rectangular',
        logo_alignment: 'center',
        width: 250
      }
    )
  },
  
  methods: {
    handleCredentialResponse(response) {
    
      // call your backend API here
      
      // the token can be accessed as: response.credential
    }
  }
}
</script>
If you also want the Google One-tap sign in, use the following inside the component or page you want to display one-tap.
<template>
...
</template>
<script>
  export default {
    mounted() {
      google.accounts.id.initialize({
        client_id: 'YOUR_CLIENT_ID',
        callback: this.handleCredentialResponse,
        context: 'signin',
      })
      google.accounts.id.prompt()
    },
    
    methods: {
      handleCredentialResponse(response) {
        // handle API calls same as above
      }
    }
  }
</script>
@Daewon25
Copy link

@srestraj thanks a lot!

@Fanreza
Copy link

Fanreza commented Jul 4, 2023

anyone have example without the google button?

@srestraj
Copy link
Author

srestraj commented Jul 7, 2023

@Fanreza, if you set the ux_mode to redirect and then handle the response server-side, you can create your own custom button. More about this here: https://developers.google.com/identity/gsi/web/reference/js-reference#ux_mode. You can also have a look at this for other options: https://developers.google.com/identity/gsi/web/reference/html-reference. If you want to use it with the pop_up mode itself, I think you can try hiding the default Google button with visibility: hidden or opacity: 0 and then add your custom button. Something like we do for custom file inputs. I haven't tried it myself, but it might work I think.

@Fanreza
Copy link

Fanreza commented Jul 10, 2023

@Fanreza, if you set the ux_mode to redirect and then handle the response server-side, you can create your own custom button. More about this here: https://developers.google.com/identity/gsi/web/reference/js-reference#ux_mode. You can also have a look at this for other options: https://developers.google.com/identity/gsi/web/reference/html-reference. If you want to use it with the pop_up mode itself, I think you can try hiding the default Google button with visibility: hidden and then add your custom button. Something like we do for custom file inputs. I haven't tried it myself, but it might work I think.

i think it will work, google button basically just a button right, we can programatically click it using javascript

@HalaSalim77
Copy link

hi, the login by google button is disapper suddenly and i got this error :

client:128 Uncaught Error
at _.$e (client:128:335)
at new sp (client:227:3)
at bq (client:246:34)
at Oo (client:244:246)
at Object.Po [as renderButton] (client:216:62)
at :8:24
at Object.insertBefore (93a0d79.js:2:45811)
at _ (93a0d79.js:2:59423)
at 93a0d79.js:2:58702
at m (93a0d79.js:2:58934)

what is the problem and how  i can fix it ?

@jirayuboss
Copy link

hi, the login by google button is disapper suddenly and i got this error :

client:128 Uncaught Error at _.$e (client:128:335) at new sp (client:227:3) at bq (client:246:34) at Oo (client:244:246) at Object.Po [as renderButton] (client:216:62) at :8:24 at Object.insertBefore (93a0d79.js:2:45811) at _ (93a0d79.js:2:59423) at 93a0d79.js:2:58702 at m (93a0d79.js:2:58934)

what is the problem and how  i can fix it ?

I also have the same issue. Did you find a way to fix it? Please help.

@srestraj
Copy link
Author

srestraj commented Aug 2, 2023

client:128 Uncaught Error
at _.$e (client:128:335)
at new sp (client:227:3)
at bq (client:246:34)
at Oo (client:244:246)
at Object.Po [as renderButton] (client:216:62)
at :8:24
at Object.insertBefore (93a0d79.js:2:45811)
at _ (93a0d79.js:2:59423)
at 93a0d79.js:2:58702
at m (93a0d79.js:2:58934)

Hi @HalaSalim77, could you send us the code snippet you have set up? Thanks.

@srestraj
Copy link
Author

srestraj commented Aug 4, 2023

Hi @HalaSalim77 and @jirayuboss , it looks like the issue is happening from the Google's side itself. As mentioned here: google/google-api-javascript-client#873 (comment), if you remove the width property or add px to it, it's fixed again. example:

google.accounts.id.renderButton(
      document.getElementById("gBtn"), {
        type: 'standard',
        size: 'large',
        text: 'signup_with',
        shape: 'pill',
        logo_alignment: 'left',
        width: '250px'
      }
)

I hope this helps.

@DwbpleaseCallMe
Copy link

Hello. I just want to display Google one tap on the website.

When I used your method to fix my nuxt2 project, there was no button on my website, but it was successful on other vue2 projects

//nuxt.config.js
{
src: 'https://accounts.google.com/gsi/client',
async: true,
defer: true,
},

//index.vue
mounted() {

setTimeout(() => {
  if (window.google && !this.token) {
    window.google.accounts.id.initialize({
      client_id: 'xxx',
      callback: this.handleGoogleOneTapCallback,
      context: 'signin',
    });
    window.google.accounts.id.prompt();


  }

}, 3000);

},

@srestraj
Copy link
Author

Hello. I just want to display Google one tap on the website.

When I used your method to fix my nuxt2 project, there was no button on my website, but it was successful on other vue2 projects

//nuxt.config.js { src: 'https://accounts.google.com/gsi/client', async: true, defer: true, },

//index.vue mounted() {

setTimeout(() => {
  if (window.google && !this.token) {
    window.google.accounts.id.initialize({
      client_id: 'xxx',
      callback: this.handleGoogleOneTapCallback,
      context: 'signin',
    });
    window.google.accounts.id.prompt();


  }

}, 3000);

},

@DwbpleaseCallMe, what's the error that you're seeing?

@DwbpleaseCallMe
Copy link

Hello. I just want to display Google one tap on the website.
When I used your method to fix my nuxt2 project, there was no button on my website, but it was successful on other vue2 projects
//nuxt.config.js { src: 'https://accounts.google.com/gsi/client', async: true, defer: true, },
//index.vue mounted() {

setTimeout(() => {
  if (window.google && !this.token) {
    window.google.accounts.id.initialize({
      client_id: 'xxx',
      callback: this.handleGoogleOneTapCallback,
      context: 'signin',
    });
    window.google.accounts.id.prompt();


  }

}, 3000);

},

@DwbpleaseCallMe, what's the error that you're seeing?

There was no error, it's just that there are no buttons displayed on the page

@srestraj
Copy link
Author

Hi @DwbpleaseCallMe, to display the button, you'd need to add the following as well.

setTimeout(() => {
  if (window.google && !this.token) {
    window.google.accounts.id.initialize({
      client_id: 'xxx',
      callback: this.handleGoogleOneTapCallback,
      context: 'signin',
    });

    // for button rendering
    window.google.accounts.id.renderButton(
      document.getElementById('googleButton'), // here, replace "googleButton" with the ID of your element that you want to populate with GSI.
      { 
        type: 'standard',
        size: 'large',
        text: 'signin_with',
        shape: 'rectangular',
        logo_alignment: 'center',
        width: '250px'
      }
    );
    window.google.accounts.id.prompt();


  }

}, 3000);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment