Search code examples
google-apisvelteworkboxsveltekit

How to load Google API client library with SvelteKit


I'm new to SvelteKit and trying to find out how to load the Google client library for Javascript.

Google tells me to do it like this:

<head>
    <script src="https://apis.google.com/js/api.js"></script>
    <script>
      function start() {
        // Initializes the client with the API key and the Translate API.
        gapi.client.init({
          'apiKey': 'YOUR_API_KEY',
          'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
        }).then(function() {
          // Executes an API request, and returns a Promise.
          // The method name `language.translations.list` comes from the API discovery.
          return gapi.client.language.translations.list({
            q: 'hello world',
            source: 'en',
            target: 'de',
          });
        }).then(function(response) {
          console.log(response.result.data.translations[0].translatedText);
        }, function(reason) {
          console.log('Error: ' + reason.result.error.message);
        });
      };

      // Loads the JavaScript client library and invokes `start` afterwards.
      gapi.load('client', start);
    </script>
  </head>

The problem is that SvelteKit doesn't allow 2 or more script tags on a page (I don't want it to be the layout page).

<script src="https://apis.google.com/js/api.js"></script>
<script>
    import { onMount } from 'svelte';
    
    gapi.client.init({...
</script>  

This results in follwing error message:

A component can only have one instance-level <script> element

As my intention is to create a progressive web app (PWA) using Workbox I don't want to import the Google library as described here because the package containing this library would become too heavy.

Any ideas how to load the Google client library? Maybe there's a Workbox way to do it? Couldn't find a SvelteKit example on Google or YouTube.

Thanks in advance


Solution

  • The svelte:head tag allows you to add resources to the document head when a component is loaded. This example should work:

    <script>
      const start = async () => {
        // Initializes the client with the API key and the Translate API.
        // @ts-ignore
        gapi.client.init({
          'apiKey': 'YOUR_API_KEY',
          'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
        }).then(function() {
          // Executes an API request, and returns a Promise.
          // The method name `language.translations.list` comes from the API discovery.
          return gapi.client.language.translations.list({
            q: 'hello world',
            source: 'en',
            target: 'de',
          });
        }).then(function(response) {
          console.log(response.result.data.translations[0].translatedText);
        }, function(reason) {
          console.log('Error: ' + reason.result.error.message);
        });
      };
    
      const initializeGapi = async () => {
        gapi.load('client', start);
      }
    </script>
    
    <svelte:head>
      <script src="https://apis.google.com/js/api.js" on:load={initializeGapi}></script>
    </svelte:head>