withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
45.4k stars 2.37k forks source link

[Resolved!] ViewTransition prevents third party js from executing on new page #9359

Closed disrae closed 8 months ago

disrae commented 9 months ago

Astro Info

Astro                    v4.0.3
Node                     v20.8.0
System                   macOS (arm64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             @astrojs/tailwind
                         @astrojs/mdx
                         @astrojs/sitemap
                         @storyblok/astro

If this issue only occurs in one browser, which browser is a problem?

Tested on Chrome and Safari, does not work on both.

Describe the Bug

Using zendesk web chat widget, the widget loads on the first load, but with ViewTransition it disappears on navigation.

What's the expected result?

the script should be able to re-execute when navigating to a new page. I tried making a new script element with an event listener (astro:page-load, astro:before-swap, astro:after-swap) and appending it to the head, this did not work. I tried appending an optional parameter to the script source to try and make it unique, also did not work.

<script is:inline>
      function loadScript() {
        console.log("Yes this is being called.");
        var script = document.createElement("script");
        script.src =
          "https://static.zdassets.com/ekr/snippet.js?key=k";
        script.id = "ze-snippet";
        document.body.appendChild(script);
      }
      document.addEventListener("astro:page-load", loadScript);
    </script>

Link to Minimal Reproducible Example

https://goose-website-ten.vercel.app/

Participation

martrapp commented 9 months ago

Hi @disrae, do you know the Astro discord server? To be honest, this sounds more like a case for the #support channel on astro discord.

I will look into your use of that 3rd party lib and see if there is an issue for astro ;-)

disrae commented 9 months ago

Thank you! I'll head over to the discord server. It seems like the zendesk chat widget requires the fulll page reload for some reason, but I'm not sure why exactly. Also, I have looked at other issues, I've read through most of the script documentation, but nothing has worked so far.

Edit: The script adds the widget to the DOM on DOMContentLoaded, which is not fired again after a transition using the View Transitions API.

martrapp commented 9 months ago

After an initial analysis, the main problem here is not in the script, but in the iframes that are later inserted into the body by this script. Iframes are reset as soon as they are moved within or between DOMs, as the swap() function does. This can be prevented by overwriting the swap() function in the astro:before-swap event listener with a version that retains the iframes and only replaces the rest of the page.

martrapp commented 8 months ago

Looking forward to disrae's feedback when he is back from vacations.

In the meanwhile, for users that found this issue on the search for help with view transitions and persisted iframes or restarting animations: I published a replacement for Astro's built-in swap() action called ReplacementSwap as part of the astro-vtbot package, the bag of tricks for Astro view transitions. This is not as automatic as Astro's swap but only needs little configuration, see https://events-3bg.pages.dev/library/ReplacementSwap/

disrae commented 8 months ago

RESOLVED!

Using @martrapp 's vtbot (ViewTransition Bag of Tricks) package, I just added the component in the header and added a wrapping div to update the main view but excluded the chat widget iframe/script tags.

I had another issue to do with localization, the chat widget needed to refresh when a user switched languages, simply adding data-astro-reload as an attribute to the language switching button leads the page to refresh and solved the issue.

<a data-astro-reload href="..."> </a>

There was yet another issue, the script I got from google tag manager provided me with a no script tag which caused an issue, I simply moved it to the bottom of my body, whereupon nothing beyond it could get messed up.

Easy peezy! πŸ₯³

I can't thank Martin enough for his shockingly quick response times, and quick and simple fixes for problems that I thought were show stoppers.

Link to the vt bot package, which can be installed with npm i astro-vtbot And then imported with

---
import ReplacementSwap from "astro-vtbot/components/ReplacementSwap.astro";
import { ViewTransitions } from "astro:transitions";
--
<head>
  <ViewTransitions />
  <ReplacementSwap />
</head>

<body>
  <div data-vtbot-replace="main">
    // Content that should transition as normal with ViewTransition.
  </div>
  <script> Or any other element will be untouched during transitions here <script>
</body>

Also, short and easy documentation in the package, so ideally follow that.

πŸ€˜πŸΌπŸ‘πŸΌ

martrapp commented 8 months ago

Great! Thank you for your great, friendly description! πŸŽ‰ πŸ₯³