14

I am creating a Sapper page, where I'd like to use Google Sign-in button. It requires data-onsuccess attribute to specify callback function. From what I was able to discover from Google's platform JS library, it looks for the function in the global/window scope.

Is there a way to access/call Svelte's component function from global webpage scope? It might be of use for interop with external libraries which cannot be loaded through import right into the component.

Example of what I am trying to do:

<script>
  function onSignComponent(user){
    console.log('Signed in');
  }
</script>

<div id="login" class="g-signin2" data-onsuccess="{onSignComponent}" data-theme="dark" />

This work when onSignComponent is in global scope but not when it is in component scope.

PhoenixS
  • 1,016
  • 1
  • 9
  • 23

2 Answers2

19

The easiest way to do this is just to put the function on window inside the component:

<script>
  window.onSignIn = user => {
    // ...
  };
</script>

<div id="login" class="g-signin2" data-onsuccess="onSignIn" data-theme="dark" />
Rich Harris
  • 28,091
  • 3
  • 84
  • 99
  • 3
    Wow, that is embarrassingly simple. I should have thought about that while trying another workaround (attaching svelte stores to window object). Thanks a lot! – PhoenixS Sep 16 '19 at 13:55
7

One way to do this would be to add <svelte:window on:xxx> directive in your component and then in the method onSignComponent raise this xxx event.

in component

<svelte:window on:loginSuccess={loginSuccess}></svelte:window>

somewhere else

const myEvent = new CustomEvent('loginSuccess', { ... some object });
window.dispatchEvent(myEvent);
Stephane Vanraes
  • 14,343
  • 2
  • 23
  • 41