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

next/script - Can't get Google Analytics inline script to load beforeInteractive - before close of <head> tag #26591

Closed
simon-olsen opened this issue Jun 25, 2021 · 8 comments · Fixed by #36364
Assignees
Labels
Script (next/script) Related to Next.js Script Optimization.

Comments

@simon-olsen
Copy link

What version of Next.js are you using?

11.0.1

What version of Node.js are you using?

10.23.0

What browser are you using?

Chrome, Firefox

What operating system are you using?

macOS

How are you deploying your application?

next start

Describe the Bug

I've just upgraded to Next.js v11.0.1 and trying out the <Script> component.

I'm trying to add the Google Analytics tag as they suggest; before the closing tag using strategy="beforeInteractive".

Here is my code for the index.tsx page

const Home: React.FC<Props> = ({ data }) => {
  return (
    <>
      <Script
        src="https://www.googletagmanager.com/gtag/js?id=[TRACKING-ID]"
        strategy="beforeInteractive"
      />
      <Script
        dangerouslySetInnerHTML={{
          __html: `window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());
          gtag('config', '[TRACKING-ID]');`,
        }}
        strategy="beforeInteractive"
      />
      <ThemeProvider theme={fullySickTheme}>
        <Head>
          <title>My Site</title>
        </Head>
...

The first <Script> with the https://www.googletagmanager.com/gtag... loads in the but the script doesn't load at all.

The only way I can load it is at the bottom of the document using the default afterInteractive or lazyOnload.

Is this by design?
Should I just let the inline portion load before the ending body tag and be done with it? I'm only trying to follow what Google recommends in GA.

I've tried the following:

  1. In a page.tsx file and in _app.tsx (docs say NOT to use _document.tsx)
  2. Tried loading inline script with dangerouslySetInnerHTML{{}} and also adding the inline script to a custom function and loading it that way, ala dangerouslySetInnerHTML={setGoogleTags(stationGA)} and {window.dataLayer = window.dataLayer || [];...}

Expected Behavior

beforeInteractive adding my inline script inside the tags.

To Reproduce

  1. Spin up a Next.js v11 site
  2. In the index.js or index.tsx page, add the following.
import Script from "next/script";

// Then in the page's component

<Script
  src="https://www.googletagmanager.com/gtag/js?id=[TRACKING-ID]"
  strategy="beforeInteractive"
/>
<Script
  dangerouslySetInnerHTML={{
  __html: `window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', '[TRACKING-ID]');`,
  }}
  strategy="beforeInteractive"
 />

Actual result

No inline script renders at all until you remove strategy="beforeInteractive"

@simon-olsen simon-olsen added the bug Issue was opened via the bug report template. label Jun 25, 2021
@simon-olsen simon-olsen changed the title next/script Can't get Google Analytics inline script to load beforeInteractive - before close of <head> tag next/script - Can't get Google Analytics inline script to load beforeInteractive - before close of <head> tag Jun 25, 2021
@timneutkens timneutkens added kind: bug and removed bug Issue was opened via the bug report template. labels Jun 25, 2021
@timneutkens timneutkens added this to the Iteration 22 milestone Jun 25, 2021
@LetItRock
Copy link
Contributor

@simon-olsen the strategy="beforeInteractive" doesn't pass the dangerouslySetInnerHTML prop to the script that is created at the end by next. I think that it's for a purpose as the docs are saying to use afterInteractive for tag managers and analytics. I've tried the code with afterInteractive and it works properly. I think that it might be because it has an impact on Web Vitals when loading with beforeInteractive.

@simon-olsen
Copy link
Author

@LetItRock thanks for the feedback. That all makes sense. I'll go with the inline script of GA at the end of the body tag. We're starting to use renderWebVitals as well, so making sure we don't mess with that is a priority.

@lxsmnsyc
Copy link

Might be related: #26240

@wedneyyuri
Copy link

@LetItRock thanks for the feedback. That all makes sense. I'll go with the inline script of GA at the end of the body tag. We're starting to use renderWebVitals as well, so making sure we don't mess with that is a priority.

@simon-olsen maybe can be better to initialize Google Analytics as a common javascript code: #26860 (comment)

// gtag.ts
const initialize = () => {
  window.dataLayer = window.dataLayer || [];
  window.gtag = function gtag() { window.dataLayer.push(arguments); }
  gtag('js', new Date());
  gtag('config', GA_TRACKING_ID);
};

// app.tsx
export default function MyApp({ Component, pageProps }) {
    useEffect(initialize, []); // this code will run only once

    return <>
        <Script src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`} />
        <Component {...pageProps} />
    </>
}

@janicklas-ralph
Copy link
Contributor

Hi. Apologize for the delayed response. I'm working on adding another strategy to load inline scripts with beforeInteractive.

I also wanted to know if there was a specific reason for loading GA before first party code? Usually we recommend loading GA with afterInteractive, but wanted to understand if that doesn't work for your usecase?

@simon-olsen
Copy link
Author

All good @janicklas-ralph.

That is the recommendation from GA. This is the instructions on their Tracking Code page in the Admin section...

This is the Global Site Tag (gtag.js) tracking code for this property. Copy and paste this code as the first item into the of every webpage you want to track. If you already have a Global Site Tag on your page, simply add the config line from the snippet below to your existing Global Site Tag.

@vinitgundeti
Copy link

vinitgundeti commented Aug 27, 2021

Hi,

I have added gtag script with strategy="afterInteractive" in _app.js and in one of my page i am tracking event on componentDidMount i am getting ReferenceError: gtag is not defined.

may i know what is the correct way to solve this.

@styfle styfle modified the milestones: 11.1.x, 12.0.4 Nov 5, 2021
@timneutkens timneutkens added the Script (next/script) Related to Next.js Script Optimization. label Nov 16, 2021
@timneutkens timneutkens removed this from the 12.0.5 milestone Nov 17, 2021
@kodiakhq kodiakhq bot closed this as completed in #36364 Apr 29, 2022
kodiakhq bot pushed a commit that referenced this issue Apr 29, 2022
…eforeInteractive` strategies (#36364)

Adds inline script functionality to `next/script` for `worker` and `beforeInteractive` strategies. 

- fixes #36318 
- fixes #26343
- fixes #26591
- fixes #26343
- fixes #26240


Co-authored-by: Janicklas Ralph <[email protected]>
@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Script (next/script) Related to Next.js Script Optimization.
Projects
None yet
8 participants