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

Return a Promise for async scripts? #240

Closed
axdyng opened this issue Jul 31, 2018 · 12 comments · Fixed by #414
Closed

Return a Promise for async scripts? #240

axdyng opened this issue Jul 31, 2018 · 12 comments · Fixed by #414

Comments

@axdyng
Copy link

axdyng commented Jul 31, 2018

Hi,

Is it possible to a Promise when loading async scripts with vue-meta? So that code that are needed to be executed after the script is loaded won't run into error.

For example a script like this:

script: [{ src: '/someAsyncScript.js', async: true }]
@pimlie
Copy link
Collaborator

pimlie commented Mar 7, 2019

The example you mentioned is already possible (maybe in the mean time) and generates the following html:

<script src="/someAsyncScript.js" async></script>

So I think we can close this issue or did I not understand your request?

@TheAlexLichter
Copy link
Member

@pimlie He is looking for sth. like a onload "hook" to execute code after the javascript has been loaded (which "guarantees" that the code finds the globals injected by it for example).

We actually need a solution for this common problem.

@pimlie
Copy link
Collaborator

pimlie commented Mar 7, 2019

Any suggestions would be appreciated, I am struggling a bit with how this would work with ssr generated code (unless we dont render the code that should run afterwards on ssr).

@TheAlexLichter
Copy link
Member

@pimlie well, for SSR that part shouldn't matter much if I recall correctly. What are your concerns there?

@pimlie
Copy link
Collaborator

pimlie commented Mar 7, 2019

Maybe I still dont understand the problem, but am I correct you need a solution for eg the problem I have with nuxt-matamo where I load an external library that sets window.Piwik and I have to wait in my plugin template until that external lib is loaded before I can start my pageview tracker?

@TheAlexLichter
Copy link
Member

@pimlie exactly. we can use the onload function (or load event) for the script tags for it. See https://developer.mozilla.org/en-US/docs/Web/Events/load ☺️

@pimlie
Copy link
Collaborator

pimlie commented Mar 7, 2019

Yeah exactly, thats what I meant with not rendering them on ssr if we'd need to dynamically create script tags to add an onload listener. With some fancy stuff we could probably ssr the first nodes of an async branch (and use an onload attribute in the html with some global reference) but all childs still need to be dynamically created then and cant be rendered on ssr I guess. That might also have an effect on render performance

@TheAlexLichter
Copy link
Member

@pimlie We'd have to test when the external scripts injected through vue-meta are loaded when using SSR first (timing-wise). I know there are differences between the first render and the navigation across routes in SPA mode too.

In the worst scenario we could make that feature SPA-mode only (where it's most useful IMO)

@pimlie
Copy link
Collaborator

pimlie commented Mar 7, 2019

hmm yes, and we could still preload those child script files which means the render performance shouldnt be effected that much I guess

@pimlie
Copy link
Collaborator

pimlie commented Apr 23, 2019

Btw, I am looking for suggestions how the api for this functionality should look like (especially from a SSR point of view). We would probably need to be able to run the listener in the local component scope, but the onload will always be on the global scope.

Potential issues I see are:

  • when there are multiple Vue apps on a page
  • when multiple components add the same script
    • without vmid
    • with same vmid
    • with unique vmids

We could probably take a look at vue-script2 for inspiration as well. My first idea would be that its probably easiest to just fire some events on the $root component or toggle a Vuex state, then you could eg listen for that event anywhere in your app and the code which adds the script tag doesnt even need to be on the same scope as the code which uses the loaded script.

@jarkt
Copy link

jarkt commented Jan 9, 2020

If you use dynamic page URLs (e.g. with article ID) and going to the same page with a different ID, the callback will not be called. But I think it should.

@jarkt
Copy link

jarkt commented Jan 10, 2020

I use a workaround for this issue, but I assume it's a bug.

destroyed () {
    document.querySelector('[data-hid="foo"]').remove()
},

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

Successfully merging a pull request may close this issue.

4 participants