dynamic script loading Nuxt route change casing crushing

Viewed 279

I create a vue component to load scripts for ads dynamically, and when the route changes, the component should destroy herself and change back when the route enters. So when the route leaves, there is no problem, but when I go to a page and then return to the same page, the ads do not appear anymore.

<template>
      <div style="display: none;">
        <slot />
      </div>
    </template>
    <script>
    export default {
      props: {
        async: { type: Boolean, default: true },
        location: { type: String, default: '' }, // or elemnt id which will select the sapce
        src: { type: String, required: false, default: '' }
      },
      data () {
        return {
          script: null
        }
      },
      beforeDestroy () {
        console.log('remove')
        if (this.script) {
          if (!this.location) {
            this?.$el?.removeChild(this?.script)
          }/** else {
            const tag = document.querySelector(this.location)
            tag?.parentNode?.removeChild(this.script)
          } */
        }
      },
      mounted () {
        console.log('add loadjs')
        this.loadJs()
      },
      methods: {
        loadJs () {
          const scriptTag = document.createElement('script')
          console.log(this.$el)
          scriptTag.async = this.async || true
          // console.log(Object.keys(this.$slots.default[0]))
          if (!this.src && this?.$slots?.default) { // when script is empty
            scriptTag.text = this?.$slots?.default[0]?.text
          } else { scriptTag.src = this.src }
          if (!this.location) { // when location is not set load after element
            this.$el.appendChild(scriptTag)
          } else {
            const location = document.querySelector(this.location)
            location.appendChild(scriptTag)
          }
          this.script = scriptTag
        }
      }
    }
    </script>

the service for the ads is

<template>
  <div>
    ads
    <div :id="id">
      <script-component>
        googletag.cmd.push(
        function() {
        googletag.display('{{ id }}');
        }
        );
      </script-component>
    </div>
  </div>
</template>
<script>
const scriptLoadder = () => import('~/components/script/scriptLoadder')
export default {
  components: {
    'script-component': scriptLoadder
  },
  props: {
    id: { type: String, required: true }
  }
}
</script>
I have another similar component for another ads service that works on server load (when I enter the home page for the first time, this works fine). The issue is when the route changes, and then I go back to the same route. Both services of ads are just not appearing.

this is how I am using the component

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
  <div>
    <google-ads id="ATF_LB_1" :key="$route.fullPath + Math.random().toString(16) " />
    or
    <google-ads id="ATF_LB_1" :key="$route.fullPath" />

    <script-component>
      {{ pageScript.HP }}
    </script-component>
    or

    <script-component :key="$route.fullPath">
      {{ pageScript.HP }}
    </script-component>
    or
    <script-component :key="$route.fullPath + Math.random().toString(16) ">
      window.alert('test on page load works when going back not')
    </script-component>
  </div>
</template>

1 Answers

So the answer is incredibly annoying. The problem was not with my code but with the provider's code. The code they gave me was intended to run on SSR only site. The only thing to pay attention to this code to "fix" the behavior is to unmount the component or key="$router.fullpath" but this will cause another issue depend on your component place. When you are inside the component and change the page, Nuxt will run the following lifecycle destroy the component and the mount on the new page (which is a problem) and then destroyed it again. This will cause latency unless you add async or defer. So to summarize, the problem was with the provider code; this component will load the script tag inside the template where you need it. I will open the npm repo for this component that works with Nuxt and create a git issue of the memory leak in a component lifecycle.

Related