skip to Main Content

I integrated the Google Sign In button (https://developers.google.com/identity/gsi/web/guides/personalized-button) in a Svelte application v.3.54.0.
The button requires a function in the global scope as a callback (data-callback attribute), e.g.:

    <div
        id="g_id_onload"
        data-client_id="<id>.apps.googleusercontent.com"
        data-context="signin"
        data-ux_mode="popup"
        data-callback="handleCredentialResponse"
        data-auto_prompt="false"
    />

    <div
        class="g_id_signin"
        data-type="standard"
        data-shape="rectangular"
        data-theme="filled_blue"
        data-text="signin_with"
        data-size="large"
        data-logo_alignment="left"
    />
            

I would like the handleCredentialResponse function to reside in a source file other than app.html, because I need to use other imported modules in the implementation, e.g.:

    function handleCredentialResponse(response) {
        
        localStorage.setItem("googleCredentials", JSON.stringify(response));
        let jwt = jwt_decode(JSON.parse(response).credential);
        localStorage.setItem('decodedJwt', JSON.stringify(jwt));
        window.location.reload();
    } 

Here I use jwt_decode which is imported from jwt-decode.
If I include handleCredentialResponse in a script tag in app.html, I get an error because jwt_decode is not defined at this level. I would have to include jwt_decode via another script tag, which I rather avoid.
On the other hand, if I write the function in a Svelte component (even with context="module"), the Google Button complains because the callback is not visible to it.
Currently I use a workaroud where I have part of the logic in app.html and part in the +layout.svelte onMount, but I really do not like it.
What is the Svelte way to deal with this need? Or, in other words, is there a place in a svelte application where I can write common code that is also visible at the root scope (and, possibly, that gets executed only once at the first loading)?

2

Answers


  1. I don’t think there is a "Svelte way" for this, as that should generally be avoided. If there is no other way, I would just make the function globally available by setting it on the window:

    onMount(() => {
      window.handleCredentialResponse = ...
    })
    

    (onMount is used because this will not work on the server during SSR.)

    Login or Signup to reply.
  2. Just create a secondary "main" script that brings the necessary function and creates the HTML Google button. That should work ok. This way, the button doesn’t exist until the corresponding function has been loaded.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search