Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

on:load does not trigger on <script src=...> tags #8301

Closed
Micka33 opened this issue Feb 21, 2023 · 3 comments
Closed

on:load does not trigger on <script src=...> tags #8301

Micka33 opened this issue Feb 21, 2023 · 3 comments

Comments

@Micka33
Copy link

Micka33 commented Feb 21, 2023

Describe the bug

In order to add external scripts (such as https://apis.google.com/js/api.js), we need to trigger some execution once they are loaded, such as in this example:

<!-- source: https://developers.google.com/sheets/api/quickstart/js ->
...
<script>
...
/**
  * Callback after api.js is loaded.
  */
function gapiLoaded() {
  gapi.load('client', initializeGapiClient);
}
...
</script>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>

The way to do it would be something such as below:

<!-- Component.svelte -->
<script lang="ts">
  import { onMount } from "svelte";

  console.log('component loaded')
  
  onMount(() => console.log('component mounted'))

  const onGapiloaded = (e) => console.log('gapi loaded'); 
  const onGISLoaded = (e) => console.log('google loaded'); 
</script>

<svelte:head>
  <script src="https://apis.google.com/js/api.js" on:load={onGapiloaded}></script>
  <script async defer src="https://accounts.google.com/gsi/client" on:load={onGISLoaded} />
</svelte:head>

However it doesn't work and currently results in the following:

component loaded
component mounted

As you can see, onGapiloaded and onGISLoaded are not triggered.

Reproduction

  1. Create a new project using npm create svelte@latest.
    Current package.json looks like below:
{
	"name": "testfolder",
	"version": "0.0.1",
	"scripts": {
		"dev": "vite dev",
		"build": "vite build",
		"preview": "vite preview",
		"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
		"lint": "prettier --plugin-search-dir . --check . && eslint .",
		"format": "prettier --plugin-search-dir . --write ."
	},
	"devDependencies": {
		"@fontsource/fira-mono": "^4.5.10",
		"@neoconfetti/svelte": "^1.0.0",
		"@sveltejs/adapter-auto": "^2.0.0",
		"@sveltejs/kit": "^1.5.0",
		"@types/cookie": "^0.5.1",
		"@typescript-eslint/eslint-plugin": "^5.45.0",
		"@typescript-eslint/parser": "^5.45.0",
		"eslint": "^8.28.0",
		"eslint-config-prettier": "^8.5.0",
		"eslint-plugin-svelte3": "^4.0.0",
		"prettier": "^2.8.0",
		"prettier-plugin-svelte": "^2.8.1",
		"svelte": "^3.54.0",
		"svelte-check": "^3.0.1",
		"tslib": "^2.4.1",
		"typescript": "^4.9.3",
		"vite": "^4.0.0"
	},
	"type": "module"
}
  1. Copy/Paste the code below in a +page.svelte of your choice and load it in your browser.
<script lang="ts">
  import { onMount } from "svelte";

  console.log('component loaded')
  
  onMount(() => console.log('component mounted'))

  const onGapiloaded = (e) => console.log('gapi loaded'); 
  const onGISLoaded = (e) => console.log('google loaded'); 
</script>

<svelte:head>
  <script src="https://apis.google.com/js/api.js" on:load={onGapiloaded}></script>
  <script async defer src="https://accounts.google.com/gsi/client" on:load={onGISLoaded} />
</svelte:head>
  1. Check the console to see the following:
component loaded
component mounted

PS: Same issue with the following versions:

"@sveltejs/kit": "^1.8.3",
"svelte": "^3.55.1",
"svelte-check": "^3.0.3",
"svelte-preprocess": "^5.0.1",
"vite": "^4.0.4",

Logs

No response

System Info

System:
    OS: macOS 12.0.1
    CPU: (8) x64 Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
    Memory: 226.09 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.18.1 - /usr/local/bin/node
    Yarn: 1.22.11 - /usr/local/bin/yarn
    npm: 8.19.2 - /usr/local/bin/npm
  Browsers:
    Brave Browser: 71.0.58.21
    Chrome: 110.0.5481.100
    Firefox: 97.0.1
    Safari: 15.1
  npmPackages:
    svelte: ^3.54.0 => 3.55.1

Severity

annoyance

@gi4no
Copy link

gi4no commented Apr 29, 2023

  • 1

mstachowiak added a commit to gitcontext/svelte-turnstile that referenced this issue Feb 2, 2024
Modifying script loading to accommodate the upcoming release of Svelte 5.
The `on:load` event for scripts placed inside `<svelte:head>` does not
fire in Svelte 5 as a result of this bug:
sveltejs/svelte#8301

Instead of loading the Cloudfare Turnstile script in `<svelte:head>`, load
the script dynamically during mount. This is functionally equivalent to
using `<svelte:head>` but accommodates an operational load event handler.
If Svelte 5 resolves Issue 8301, this is not needed.
@trueadm trueadm self-assigned this Feb 13, 2024
@trueadm
Copy link
Contributor

trueadm commented Feb 13, 2024

This is something that also was not working in Svelte 4. Specifically, the script element has already loaded from SSR and when hydration occurs, the event listener gets added too late.

@Rich-Harris
Copy link
Member

This is working as expected, but there's a case to be made that we should fire synthetic load events during hydration. Closing this in favour of #11046

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants