Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Sign In With Google button disappear after I render it the second time?

I am using the Sign In With Google button from Google Identity. I have put the HTML from this button documentation page into a React component. Looks like this:

export default function GoogleLoginButton() {

  return (
    <>
      <div
        id="g_id_onload"
        data-client_id="XXXXXX"
        data-auto_prompt="false"
      ></div>
      <div
        className="g_id_signin"
        data-type="standard"
        data-size="large"
        data-theme="outline"
        data-text="sign_in_with"
        data-shape="rectangular"
        data-logo_alignment="left"
      ></div>
    </>
  );
}

On loading the page the first time the Google sign-in button appears correctly and I can log in. The sign-in button is then replaced by a log-out button. The problem is that when I click the log-out button which should render the Google sign-in button again, it doesn't reappear! Why is that?

I can add that refreshing the page after logging out brings back the Google button.

like image 566
Stian Jørgensrud Avatar asked Dec 06 '25 06:12

Stian Jørgensrud


2 Answers

As Stian says, the google script injects the google button once the app renders. The problem is that if you re-render the component where your button is located it will disappear because the google script was already executed, and won't be executed in future re-renders (it won't inject the google button again).

A different solution is to call window.google.accounts.id.renderButton inside an useEffect, that useEffect should be placed inside the component that is re-rendered. This will re-inject the google button each time the useEffect is called (comoponent is re-rendered).

The first argument the renderButton method receives should be a ref to a div, the google script will inject the sign-in button inside that div.

NOTE: Remember to first initialize the google script calling google.accounts.id.initialize

Here's the example:

const divRef = useRef(null);

useEffect(() => {
  if (divRef.current) {
    window.google.accounts.id.initialize({
      client_id: <YOUR_CLIENT_ID_GOES_HERE>,
      callback: (res, error) => {
        // This is the function that will be executed once the authentication with google is finished
      },
    });
    window.google.accounts.id.renderButton(divRef.current, {
      theme: 'filled_blue',
      size: 'medium',
      type: 'standard',
      text: 'continue_with',
    });
  }
}, [divRef.current]);

return (
  {/* Other stuff in your component... */}

  {/* Google sign in button -> */} <div ref={divRef} />
);
like image 66
Alex Rendón Avatar answered Dec 08 '25 19:12

Alex Rendón


I found another solution to this problem by creating a useEffect hook that inserts the Google button <script> tag into the DOM every time the component renders. This prevents the button from disappearing when navigating away from the page and back again. The full React component then looks as follows:

const GoogleButton = () => {
  useEffect(() => {
    const script = document.createElement('script');

    script.src = 'https://accounts.google.com/gsi/client';
    script.async = true;
    script.defer = true;

    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    };
  }, []);

  return (
    <>
      <div
        id='g_id_onload'
        data-client_id='your-client-id'
      />
      <div
        className='g_id_signin'
        data-type='standard'
        data-size='large'
        data-theme='outline'
        data-text='sign_in_with'
        data-shape='rectangular'
        data-logo_alignment='center'
      />
    </>
  );
};
like image 43
rj3005 Avatar answered Dec 08 '25 21:12

rj3005



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!