Skip to content

Instantly share code, notes, and snippets.

@pmckee11
Last active February 13, 2023 14:21
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmckee11/13b1dffbf1d271a782ed7f65480b978f to your computer and use it in GitHub Desktop.
Save pmckee11/13b1dffbf1d271a782ed7f65480b978f to your computer and use it in GitHub Desktop.
New (Aug 2021) Google Sign In Button in React
import React, { FunctionComponent, useEffect, useState } from 'react';
import { Helmet, HelmetProvider, HelmetTags } from 'react-helmet-async';
const googleUrl = 'https://accounts.google.com/gsi/client';
export interface GoogleCredentialResponse {
credential: string;
}
interface GoogleButtonParams {
onCredentialResponse: (response: GoogleCredentialResponse) => void;
}
const GoogleButton: FunctionComponent<GoogleButtonParams> = ({
onCredentialResponse,
}) => {
const [scriptLoaded, setScriptLoaded] = useState(
typeof window !== 'undefined' && typeof (window as any).google !== 'undefined'
);
const divRef = React.createRef<HTMLDivElement>();
// Helmet does not support the onLoad property of the script tag, so we have to manually add it like so
const handleChangeClientState = (newState: any, addedTags: HelmetTags) => {
if (addedTags && addedTags.scriptTags) {
const foundScript = addedTags.scriptTags.find(
({ src }) => src === googleUrl
);
if (foundScript) {
foundScript.addEventListener('load', () => setScriptLoaded(true), {
once: true,
});
}
}
};
useEffect(() => {
if (scriptLoaded && divRef.current) {
(window as any).google.accounts.id.initialize({
client_id: 'YOUR-GOOGLE-CLIENT-ID-HERE',
callback: onCredentialResponse,
});
(window as any).google.accounts.id.renderButton(divRef.current, {
theme: 'outline',
size: 'large',
width: divRef.current.clientWidth,
});
}
}, [scriptLoaded, divRef, onCredentialResponse]);
return (
<>
<HelmetProvider>
<Helmet onChangeClientState={handleChangeClientState}>
<script src={googleUrl} async defer />
</Helmet>
</HelmetProvider>
<div ref={divRef} />
</>
);
};
export default GoogleButton;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment