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 <Script> component doesn't render if inside next/head <Head> component #27498

Closed
zackdotcomputer opened this issue Jul 26, 2021 · 6 comments
Labels
bug Issue was opened via the bug report template.

Comments

@zackdotcomputer
Copy link
Contributor

What version of Next.js are you using?

11.0.1

What version of Node.js are you using?

14.17.0

What browser are you using?

Chrome

What operating system are you using?

MacOS

How are you deploying your application?

Netlify

Describe the Bug

I'm following the demands of next lint, attempting to upgrade all my previous <script async src=...> components to the Script component. I ran into an issue upgrading the Google Analytics tag: when using <Script> analytics is not loaded into the page, but when using <script> it is.

Finally correlated this issue with the fact that the <Script> component was stuck alongside my <meta> tags inside of a Next <Head> component. Moving it outside of the <Head> also fixed the issue.

Expected Behavior

Expected behavior would be that <Script> would function anywhere that <script> functions (except for _document, since that caveat is noted in the docs). If it is inside the <Head>, it should wind up loading the same as if it weren't.

To Reproduce

My setup:

./src/SetupGoogleAnalytics.tsx

const gaId = "UA-XXXXXXXX-1";

export default function SetupGoogleAnalytics() {
  useEffect(() => {
    if (typeof window !== "undefined" && !(window as any).gtag && gaId) {
      const anyWindow = window as any;
      anyWindow.dataLayer = anyWindow.dataLayer || [];
      anyWindow.gtag = function gtag() {
        // eslint-disable-next-line prefer-rest-params
        anyWindow.dataLayer.push(arguments);
      };
      anyWindow.gtag("js", new Date());
      anyWindow.gtag("config", gaId);
    }
  }, []);

  if (!gaId) {
    return null;
  }

  return (
    <>
      <Script src={`https://www.googletagmanager.com/gtag/js?id=${gaId}`} />
    </>
  );
}

./pages/index.tsx

import Head from "next/head";
import SetupGoogleAnalytics from "../components/SetupGoogleAnalytics";

export default function Home() {
  return (
    <article>
      <Head>
        <title>Repro</title>
        <SetupGoogleAnalytics />
      </Head>
      <p>This should not have analytics enabled.</p>
    </article>
  );
}

./pages/works.tsx

import Head from "next/head";
import SetupGoogleAnalytics from "../components/SetupGoogleAnalytics";

export default function Home() {
  return (
    <article>
      <Head>
        <title>Repro</title>
      </Head>
      <SetupGoogleAnalytics />
      <p>This <strong>should</strong> have analytics enabled.</p>
    </article>
  );
}
@zackdotcomputer zackdotcomputer added the bug Issue was opened via the bug report template. label Jul 26, 2021
@stefanprobst
Copy link
Contributor

The docs say: "With next/script, you no longer need to wrap scripts in next/head."

There is also this PR to add a new lint rule to check for next/script inside next/head.

@zackdotcomputer
Copy link
Contributor Author

@stefanprobst I had seen that the documentation says you no longer need to wrap scripts in head, but I did not interpret that meaning that you must not wrap the scripts in next/head. If the intention is that it is now a requirement to move scripts outside of any <Head> components, I think that requirement should be made more explicit.

(Though as an aside, this does make me curious why <Script> would require that? It makes migration more difficult since now it's not just a simple "swap script for Script" change.)

@zackdotcomputer
Copy link
Contributor Author

I followed the trail back and see that this commit previously included a clearer caveat that one shouldn't use Script inside of Head, though again I think the documentation really should say "must not" and the tag should potentially throw or console.error rather than silently fail in this case.

Agreed that PR 27257 will help here.

@zackdotcomputer
Copy link
Contributor Author

I added a PR (above) restoring a warning in the docs about this gotcha. I think between that and the new lint rule, this issue could be closed without needing to change functionality of either component.

kodiakhq bot pushed a commit that referenced this issue Aug 1, 2021
Documentation to help future developers avoid #27498 

## Documentation / Examples

- [X] Make sure the linting passes
flybayer pushed a commit to blitz-js/next.js that referenced this issue Aug 19, 2021
…#27534)

Documentation to help future developers avoid vercel#27498 

## Documentation / Examples

- [X] Make sure the linting passes
@jankaifer
Copy link
Contributor

This looks like a forgotten issue. I'll close it.

@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 Dec 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

3 participants