1- import React , { useEffect , useState } from "react" ;
1+ import React , { useEffect , useState , useRef } from "react" ;
22
33import Avatar from "@mui/material/Avatar" ;
44import CssBaseline from "@mui/material/CssBaseline" ;
@@ -42,12 +42,68 @@ function Copyright(props: any) {
4242
4343const theme = createTheme ( ) ;
4444
45+ // useLoadGsiScript from
46+ // https://github.com/MomenSherif/react-oauth/blob/244d2b970d910af18a1bfdf2a74625834e087b40/packages/%40react-oauth/google/src/GoogleOAuthProvider.tsx
47+ interface UseLoadGsiScriptOptions {
48+ /**
49+ * Nonce applied to GSI script tag. Propagates to GSI's inline style tag
50+ */
51+ nonce ?: string ;
52+ /**
53+ * Callback fires on load [gsi](https://accounts.google.com/gsi/client) script success
54+ */
55+ onScriptLoadSuccess ?: ( ) => void ;
56+ /**
57+ * Callback fires on load [gsi](https://accounts.google.com/gsi/client) script failure
58+ */
59+ onScriptLoadError ?: ( ) => void ;
60+ }
61+
62+ function useLoadGsiScript ( options : UseLoadGsiScriptOptions = { } ) : boolean {
63+ const { nonce, onScriptLoadSuccess, onScriptLoadError } = options ;
64+
65+ const [ scriptLoadedSuccessfully , setScriptLoadedSuccessfully ] =
66+ useState ( false ) ;
67+
68+ const onScriptLoadSuccessRef = useRef ( onScriptLoadSuccess ) ;
69+ onScriptLoadSuccessRef . current = onScriptLoadSuccess ;
70+
71+ const onScriptLoadErrorRef = useRef ( onScriptLoadError ) ;
72+ onScriptLoadErrorRef . current = onScriptLoadError ;
73+
74+ useEffect ( ( ) => {
75+ const scriptTag = document . createElement ( "script" ) ;
76+ scriptTag . src = "https://accounts.google.com/gsi/client" ;
77+ scriptTag . async = true ;
78+ scriptTag . defer = true ;
79+ scriptTag . nonce = nonce ;
80+ scriptTag . onload = ( ) => {
81+ setScriptLoadedSuccessfully ( true ) ;
82+ onScriptLoadSuccessRef . current ?.( ) ;
83+ } ;
84+ scriptTag . onerror = ( ) => {
85+ setScriptLoadedSuccessfully ( false ) ;
86+ onScriptLoadErrorRef . current ?.( ) ;
87+ } ;
88+
89+ document . body . appendChild ( scriptTag ) ;
90+
91+ return ( ) => {
92+ document . body . removeChild ( scriptTag ) ;
93+ } ;
94+ } , [ nonce ] ) ;
95+
96+ return scriptLoadedSuccessfully ;
97+ }
98+
4599declare var google : any ;
46100
47101export function GoogleSignin ( ) {
48102 const { handleGoogle } = useAuth ( ) ;
103+ const scriptLoadedSuccessfully = useLoadGsiScript ( ) ;
49104
50105 useEffect ( ( ) => {
106+ if ( ! scriptLoadedSuccessfully ) return ;
51107 console . log ( "nodeenv" , process . env . NODE_ENV ) ;
52108 let client_id =
53109 process . env . NODE_ENV === "development"
@@ -62,7 +118,7 @@ export function GoogleSignin() {
62118 document . getElementById ( "googleLoginDiv" ) ,
63119 { theme : "outline" , size : "large" } // customization attributes
64120 ) ;
65- } , [ handleGoogle ] ) ;
121+ } , [ handleGoogle , scriptLoadedSuccessfully ] ) ;
66122 return < Box id = "googleLoginDiv" > </ Box > ;
67123}
68124
0 commit comments