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 using beforeInteractive strategy don't work with alert #26343

Closed
dudusotero opened this issue Jun 18, 2021 · 29 comments · Fixed by #36364
Closed

next/script using beforeInteractive strategy don't work with alert #26343

dudusotero opened this issue Jun 18, 2021 · 29 comments · Fixed by #36364
Assignees
Labels
Script (next/script) Related to Next.js Script Optimization.

Comments

@dudusotero
Copy link

What version of Next.js are you using?

11.0.0

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?

next start

Describe the Bug

When I try to add next/script into "_document" or "_app" files calling a inline alert function, don't work using beforeInteractive strategy, but when I don't explicitly inform a strategy value, it works.

image

Expected Behavior

Should work with beforeInteractive strategy inside _document.js or _app.js.

To Reproduce

Just add <Script strategy="beforeInteractive">{`alert('Not work')`}</Script> to _document.js or _app.js, and try to run with next build && next start.

@dudusotero dudusotero added the bug Issue was opened via the bug report template. label Jun 18, 2021
@balazsorban44
Copy link
Member

The docs says it shouldn't be used inside _document

https://nextjs.org/docs/basic-features/script

haven't tried _app

@prichodko
Copy link
Contributor

prichodko commented Jun 19, 2021

@balazsorban44 is correct regarding the _document usage.

There is an issue, however, with a next/script used as a children or through dangerouslySetInnerHTML and beforeInteractive strategy.

In this case the value of src is (unknown):

image

The issue seems to be that renderToStaticHTMLMarkup renders the scriptLoader object as it is, not handling it similarly to this block of code.

@prichodko
Copy link
Contributor

Related: #26240

@janicklas-ralph
Copy link
Contributor

Hi. Apologize for the delayed response. An update on this - It was intentional to not allow inline scripts with beforeInteractive since we noticed it hurt performance. I'm working on adding another strategy to load inline scripts with beforeInteractive.

@janicklas-ralph janicklas-ralph self-assigned this Aug 17, 2021
@zmarty
Copy link

zmarty commented Aug 19, 2021

Thanks, we need this to load the Application Insights JS SDK

@prichodko
Copy link
Contributor

prichodko commented Aug 19, 2021

@janicklas-ralph thanks for the heads-up.

My initial idea was to insert a simple code that checks for the presence of the authentication token. But then I had a moment of realization. Isn't inline script together with beforeInteractive strategy same as this code?

<Head>
  <script dangerouslySetInnerHTML={{
    __html: ` // code here`
  }}
  />
<Head />

@prichodko
Copy link
Contributor

Another use-case is a code that detects user selected light / dark theme, to avoid flickering on the first load.

@durdenx
Copy link

durdenx commented Sep 7, 2021

Is next/script working in _app ?

@balazsorban44
Copy link
Member

Per the docs, _app is fine:

Note:
next/script must not be placed in either a next/head component or in pages/_document.js.

https://nextjs.org/docs/basic-features/script#usage

@RyanClementsHax
Copy link
Contributor

Per the docs, _app is fine:

Note:
next/script must not be placed in either a next/head component or in pages/_document.js.

https://nextjs.org/docs/basic-features/script#usage

@durdenx _app is fine, although be aware of rehyrdation errors as the code that gets interpolated into the script may differ between client and server.

@RyanClementsHax
Copy link
Contributor

@janicklas-ralph thanks for the heads-up.

My initial idea was to insert a simple code that checks for the presence of the authentication token. But then I had a moment of realization. Isn't inline script together with beforeInteractive strategy same as this code?

<Head>
  <script dangerouslySetInnerHTML={{
    __html: ` // code here`
  }}
  />
<Head />

Another use-case is a code that detects user selected light / dark theme, to avoid flickering on the first load.

Funny enough you should mention it, this is exactly the use case and strategy that Josh Comeau writes about in his article on how to achieve the perfect dark theme, and how Brian Lovin implemented this technique in his personal site which is written using nextjs

Side note: if anyone is happening to stumble on this looking to load scripts before interactive using this component, it seems to not work on version 12 of next either.

@imsamad
Copy link

imsamad commented Nov 16, 2021

It would not work , bcoz in inline Script only "lazyOnload" and afterInteractive" strategies are are allowed .

@timneutkens timneutkens added the Script (next/script) Related to Next.js Script Optimization. label Nov 19, 2021
@mishrsoumitra
Copy link

Should this not be added to the docs that dangerouslySetInnerHTML does not work with beforeInteractive strategy?

@MincePie
Copy link

Where do I put scripts if I can't put them in _document?

@prichodko
Copy link
Contributor

Wherever you want. If you need it on every page, then _app.

@MincePie
Copy link

Does it go inside the head tag of _app?

@prichodko
Copy link
Contributor

Nope, this should work:

import Script from 'next/script'

export default function App() {
  return (
    <>
      <Script src="https://www.google-analytics.com/analytics.js" />
      <h1>Hello, world!</h1>
    </>
  )
}

@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 <6142074+janicklas-ralph@users.noreply.github.com>
@xd-hearst
Copy link

xd-hearst commented May 21, 2022

seems the narrative has changed regarding this in the doc: https://nextjs.org/docs/basic-features/script#beforeinteractive

It is stated that:

This strategy only works inside _document.js

However, if you try with their example, it does not work at all:

// In _document.js
import { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
        <Script
          src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"
          strategy="beforeInteractive"
        ></Script>
      </body>
    </Html>
  )
}

Put it in the app does work.

I am curious why

@martinnabhan
Copy link
Contributor

We have the same issue. As soon as we moved our next/script polyfills to _document we started catching errors from our users. Moving the script tags back to _app solved it.

@firebirdsonic
Copy link

firebirdsonic commented Jun 11, 2022

Same

We have the same issue. As soon as we moved our next/script polyfills to _document we started catching errors from our users. Moving the script tags back to _app solved it.

Same here. The script doesn't load and doesn't appear in the dom when the script is used in _document. I tried it with the example nextjs app and add the code they used on their site.

@balazsorban44
Copy link
Member

Please try the next@canary release. If you still see this issue, please open an issue with a reproduction.

@aboqasem
Copy link

Hi @balazsorban44, here is an issue regarding the problem #37741

@xd-hearst
Copy link

Sorry for saying this, but I think it is bad that next js official doc continues to leave the non-working/erroneous example out there. Knowingly.

@balazsorban44
Copy link
Member

Sorry for the confusion here, let me try to explain.

Yes, the narrative has changed, when using Script together with the beforeInteractive strategy, it should now be placed in _document. (Reflected in the docs now, and explained why. Please see https://nextjs.org/docs/basic-features/script#beforeinteractive.)

The way it currently works is only if you put Script in Head. There is a known issue when Script is in Body as pointed out #26343 (comment)

We are aware of that, please see: #37741 (comment), and going to fix this soon!

Hope that helps! 💚

@rmuratov
Copy link

rmuratov commented Jun 21, 2022

Yes, the narrative has changed, when using Script together with the beforeInteractive strategy, it should now be placed in _document. (Reflected in the docs now, and explained why. Please see https://nextjs.org/docs/basic-features/script#beforeinteractive.)

The way it currently works is only if you put Script in Head. There is a known issue when Script is in Body as pointed out #26343 (comment)

Is that correct only for canary? We are at 12.0.4 right now and it seems not to work as said.

upd: For us it doesn't work in canary either. Will try something else...

@balazsorban44
Copy link
Member

@rmuratov please create an issue with a reproduction and we can have a look! 🙏

@andrewfritz86
Copy link

This is working perfectly now for me in at 12.1.7-canary.44. Would highly recommend throwing something in the official documentation to highlight that the Script component in the _document does not work as described in the current stable release.

@timneutkens
Copy link
Member

12.2 is out since yesterday!

@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 Jul 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.