partytown icon indicating copy to clipboard operation
partytown copied to clipboard

Scripts not being intercepted on a client-side transition

Open housseindjirdeh opened this issue 3 years ago • 15 comments

Hi folks! I'm noticing an interesting issue adding Partytown to a Next.js app and I'm not sure if it's intended behavior or if I'm just doing something wrong 😅.

Consider a basic Next.js application with two routes that have the <Partytown/> React component included in its head along with a 3P script with type="text/partytown":

Page 1:

import { Partytown } from "@builder.io/partytown/react";

const Home = () => {
  return (
    <>
      <Head>
        <Partytown debug={true} logScriptExecution={true} />
        <script
          src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js"
          type="text/partytown"
        />
      </Head>
      <Link href="/about">About</Link>
    </>
  );
};

Page 2:

import { Partytown } from "@builder.io/partytown/react";

const About = () => {
  return (
    <>
      <Head>
        <Partytown debug={true} logScriptExecution={true} />
        <script
          src="https://connect.facebook.net/en_US/sdk.js"
          type="text/partytown"
        />
      </Head>
      <Link href="/">About</Link>
    </>
  );
};

When I reload either of the two pages where the Partytown snippet gets injected server-side, the script seems to be intercepted by the service worker correctly and I see that it gets executed via the debug logs:

Screen Shot 2022-02-12 at 12 29 15 PM

However when I navigate from one page to the other via a client-side transition, the script on the second page doesn't seem to be fetched or executed. Here's a video that shows how the script on the second page doesn't load on a client-side navigation but does during an SSR reload:

https://user-images.githubusercontent.com/12476932/153726259-1ddb5dd8-694e-4ae8-98ce-3e5ec436d0c7.mov

Similarly, if I remove the script in Page 1 and then navigate to Page 2 where the Partytown snippet should get injected and instantiated client-side, it doesn't seem to work as well 🤔.


I set up a reproduction here: https://codesandbox.io/s/mystifying-goldberg-o12j7?file=/pages/index.js. Please let me know if you need any more details and/or if I can help debug where the potential issue may be happening.

housseindjirdeh avatar Feb 12 '22 18:02 housseindjirdeh

Hi, I have the same question too: I successfully loaded the GTM script on my custom Next.js Document page and, at start, the pageview event is triggered as expected.

I tried, then, to push the pageview event client side, listening on "routeChangeComplete" router event but the command is never forwarded to the service worker:

useEffect(() => {
    const pageview = (url) => {
      dataLayer.push({
        event: "pageview",
        page: url,
      })
    }

    router.events.on("routeChangeComplete", pageview)

    return () => {
      router.events.off("routeChangeComplete", pageview)
    }
}, [router.events])

valse avatar Feb 26 '22 23:02 valse

We're encountering the same with Nuxt. I think implementing with MutationObserver might be a straightforward approach?

danielroe avatar Mar 10 '22 14:03 danielroe

I faced this same issue while implementing this with Nuxt2. Initial event works well but using window.dataLayer.push(event) doesn't trigger GTM request for that event.

I've created simple implementation here nuxt2-partytown-demo

If this issue is fixed then I'm planning to write a module/plugin for Nuxt2 to implement Partytown

itsmnthn avatar Mar 27 '22 17:03 itsmnthn

I ran gtag integration test locally and it seems button click is not sending event as it suppose to send { event: 'button-click', from: 'partytown' }

test/integration/gtag at https://github.com/BuilderIO/partytown/blob/main/tests/integrations/gtm/index.html`

Also tried live test https://partytown.builder.io/tests/integrations/gtm/ with same problem.

Is this expected behaviour and I am not understanding something or there is problem?

itsmnthn avatar Mar 27 '22 18:03 itsmnthn

I am getting the same issue. I cannot find a way to send a page view event to the Partytown GTM script from the main thread in Next.js.

CruScanlan avatar Mar 31 '22 04:03 CruScanlan

Check this demo nuxt2-partytown-demo I tried using hidden input on main thread and dispatchEvent('change') on button click and listen the same input change event in text/partytown gtag script and use gtag('pageView', 'about') but with no luck.

doing window.dataLayer.push inside partytown script where gtag is initialised works only once, letter it just doesn't send new event after it.

itsmnthn avatar Mar 31 '22 17:03 itsmnthn

Hi, I finally found how to use GA with Partytown and Next.js.... here my post about it: I'd like to try with GTM too.

valse avatar Mar 31 '22 20:03 valse

@adamdbradley what's would be the correct approach here to help implement?

  1. Create mutation observer that listens to newly created script tags with type text/partytown and route them through partytown.
  2. Create a function that you can call to inject partytown tags?

One would be the most automated one, where you don't have to think about implementation details as a end-user. The second option would be more on the framework side, where you can do the logic with a Script component.

wardpeet avatar Apr 07 '22 17:04 wardpeet

This is because the Playwright component mounts a snippet to the header, this snippet, only checks once for the existence of the text/partytown scripts, when the document is loaded. The logic does not rerun when page transition happens. https://github.com/BuilderIO/partytown/blob/main/src/lib/main/snippet.ts#L156

Edit: I've scratched around a bit more and it seems that the worker uses requestAnimationFrame, to detect the next scripts. I'll try to debug it some more, I'm annoyed by this bug, especially since it's been open for so long.

mrakus-sofomo avatar Oct 17 '23 20:10 mrakus-sofomo

Thanks for your help @mrakus-sofomo let's try to solve this issue

gioboa avatar Oct 17 '23 21:10 gioboa

@gioboa Is this issue still present in nextjs worker script? https://nextjs.org/docs/pages/building-your-application/optimizing/scripts#offloading-scripts-to-a-web-worker-experimental

mrakus-sofomo avatar Mar 26 '24 18:03 mrakus-sofomo

@gioboa Is this issue still present in nextjs worker script? https://nextjs.org/docs/pages/building-your-application/optimizing/scripts#offloading-scripts-to-a-web-worker-experimental

I guess so. I didn't solve it yet

gioboa avatar Mar 26 '24 22:03 gioboa