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

noscript tags prevent head contents from updating #40

Closed
Tanguy-Magnaudet opened this issue Oct 1, 2023 · 8 comments
Closed

noscript tags prevent head contents from updating #40

Tanguy-Magnaudet opened this issue Oct 1, 2023 · 8 comments

Comments

@Tanguy-Magnaudet
Copy link

Tanguy-Magnaudet commented Oct 1, 2023

Description of the issue

I want to add GA, Linkedin & Facebook Pixels tracking scripts in the head of my pages, it makes the styles disappears when I change the page, but not my JS from Astro. It also log replicated GA / FB / Linkedin tracking instance.

I tried to use the scripts-plugin with optin enabled but it doesn't solve the issue.

Is there something I'm doing wrong ? What should I do to make it work ?
I know there is a GA Plugin, but since I have also FB pixel & Linkedin Tracking I'd like a solution that can be replicable to these 2 other scripts.

How to reproduce the issue

It's the head of my astro project :

	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<!-- Meta Pixel Code -->
		<script>
			!function(f,b,e,v,n,t,s)
			{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
			n.callMethod.apply(n,arguments):n.queue.push(arguments)};
			if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
			n.queue=[];t=b.createElement(e);t.async=!0;
			t.src=v;s=b.getElementsByTagName(e)[0];
			s.parentNode.insertBefore(t,s)}(window, document,'script',
			'https://connect.facebook.net/en_US/fbevents.js');
			fbq('init', 'blablabla');
			fbq('track', 'PageView');
		</script>
		<noscript><img height="1" width="1" style="display:none"
		src="https://www.facebook.com/tr?id=blablabla&ev=PageView&noscript=1"
		/></noscript>
		<!-- End Meta Pixel Code -->

		<!-- Google tag (gtag.js) -->
		<script async src="https://www.googletagmanager.com/gtag/js?id=G-blablabla"></script>
		<script>
			window.dataLayer = window.dataLayer || [];
			function gtag(){dataLayer.push(arguments);}
			gtag('js', new Date());

			gtag('config', 'G-blablabla');
		</script>

		<script type="text/javascript">
			_linkedin_partner_id = "blablabla";
			window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
			window._linkedin_data_partner_ids.push(_linkedin_partner_id);
		</script>
		<script type="text/javascript">
		(function(l) {
			if (!l){window.lintrk = function(a,b){window.lintrk.q.push([a,b])};
			window.lintrk.q=[]}
			var s = document.getElementsByTagName("script")[0];
			var b = document.createElement("script");
			b.type = "text/javascript";b.async = true;
			b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
			s.parentNode.insertBefore(b, s);})(window.lintrk);
		</script>
		<noscript>
			<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=balblalba&fmt=gif" />
		</noscript>
		<SEO seo={props.seo} />
	</head>

Context and environment

    swup({
      theme: "overlay",
      containers: ['#transitionnable'],
      animationSelector: 'transition-',
      smoothScrolling: true,
      debug: process.env.WP_ENV === "development",
      preload: false,
      globalInstance: true,
      plugins: [new SwupScriptsPlugin({
        body: false,
        optin: true
      })]
    })
@daun
Copy link
Member

daun commented Oct 1, 2023

Hi 🥦

  1. Can you clarify what you mean by "crashes the page"? A console log message or something would be useful to figure out the issue.
  2. I'm surprised your example code compiles at all. The integration doesn't have a plugins option and isn't able to run plugins. If you need to configure plugins yourself, we recommend following the manual setup process detailed in the latter part of the readme.

@Tanguy-Magnaudet
Copy link
Author

Hi,

Can you clarify what you mean by "crashes the page"? A console log message or something would be useful to figure out the issue.

Yes crash is not the right word, sorry about that.
I meant, the page transition happens, and then, the new page is loaded without any styles.

When I inspect the element, I can see every <script> and <style> tags imported by Astro getting removed in the new page. This only happens when there is theses third party elements in the page.

@daun daun changed the title Tracking scripts crash the page. Tracking scripts prevent new stylesheets from loading Oct 2, 2023
@daun
Copy link
Member

daun commented Oct 2, 2023

Alright, I've renamed the issue to reflect what seems to be happening here. To narrow this down, here's a few suggestions:

  • Are you getting any console errors at all?
  • Try to only include the meta script, then only the gtag scripts, etc., to see if it's a specific one of these
  • Try adding a data-swup-ignore-script script on these scripts to see if that fixes it. You probably don't want these to be executed every single time you're changing the page — you'd just want to track a new page view instead of initialising the whole tracker again and again

@Tanguy-Magnaudet
Copy link
Author

Tanguy-Magnaudet commented Oct 2, 2023

Try to only include the meta script, then only the gtag scripts, etc., to see if it's a specific one of these
Yes, forgot to mention :

  • GA alone works,
  • meta pixel or linkedin alone makes the problem appear.

Are you getting any console errors at all?
No, only a warning : fbevents.js:24 [Meta Pixel] - Duplicate Pixel ID: blablabla.

Try adding a data-swup-ignore-script script on these scripts to see if that fixes it.
It silence the warning I mentioned, but the page is still loosing the styles,


Ok I got it after a flash of lucidity :

The problem is coming from the tags :

<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=blabla&ev=PageView&noscript=1"
/></noscript>

// and

<noscript>
<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=blabla&fmt=gif" />
</noscript>

Removing them fix it.
I don't know if it is truelly related to swup integration or astro itself ?

@daun
Copy link
Member

daun commented Oct 2, 2023

Okay, so it's the noscript tag triggering this. Interesting. I'll see if I can reproduce this with a generic test case. I assume it's a problem with the Head Plugin choking on those tags, but let's see. Thanks for reporting, in any case.

@daun
Copy link
Member

daun commented Oct 2, 2023

I've done a little investigating and this seems to be an issue with how browsers treat noscript tags when parsing text/html strings into a document. I'll transfer this issue to the Head Plugin, which is ultimately where this needs to be handled.

See this section on MDN about DOMParser.parseFromString:

A value of text/html will invoke the HTML parser, and the method will return an HTMLDocument. Any <script> element gets marked non-executable, and the contents of <noscript> are parsed as markup.

@daun daun transferred this issue from swup/astro Oct 2, 2023
@daun daun changed the title Tracking scripts prevent new stylesheets from loading noscript tags prevent head contents from updating Oct 2, 2023
@daun daun changed the title noscript tags prevent head contents from updating noscript tags prevent head contents from updating Oct 2, 2023
@daun
Copy link
Member

daun commented Oct 2, 2023

@Tanguy-Magnaudet I think I've found the culprit.

If the DOMParser encounters child nodes inside a noscript tag that aren't allowed in the head element, it will implicitly interpret this as the end of the head element and start the body element, moving the noscript and any following tags into the body. See this StackOverflow question for details. This is what happens in your case: img tags aren't allowed in the head, so it moves the img as well as all following stylesheets into the body. The Head Plugin now thinks there's no new stylesheets on the new page.

The browser itself seems to be more lenient and allows img tags just fine in the head on initial load, it just appears as an issue once we're parsing HTML ourselves in JS. Probably security-related to avoid cross-site scripting attacks and the like.

The proof is that using valid head tags like meta seems to work fine:

<!-- doesn't work: won't find new stylesheets -->
<noscript><img height="1" width="1"  src="https://www.facebook.com/..." /></noscript>

<!-- works: loads new stylesheets -->
<noscript><meta name="noscript" content="Noscript in head" /></noscript>

The solution here is easy: move the noscript tags into the body.

I'll close this for now as there's not much we can do on the library side.

@daun daun closed this as completed Oct 2, 2023
@daun
Copy link
Member

daun commented Oct 2, 2023

We'll add a warning to the readme for people trying to debug this in the future.

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

2 participants