0

I have a 3rd party script that requires me to define a global window.varforthem before they load. I took a look at the nextJS docs for this. It's done in a way where eslint and other plugins won't work aside from it being less readable for a long configuration object. If I use my public folder like <Script src="/scripts/forthirdparty.js" />, it gets slapped on the page without being optimized like the rest of the assets within _next/static. On top of that, the max-age header is set to 0 so my CDN doesn't cache that misc file. is there a better way to handle this? If not, how can I make sure my static file gets a custom max age?

I tried to use a regular <script> vs <Script> in the <Head> tag after Steve Tomlin's link below.

My inline scripts need some server config to work which makes it a bit more complicated.

// earlier in the method
const conf = `window.config = ${JSON.stringify(pageProps.config)}`;
const { config: pageConfig } = pageProps;

// later on
<Head>
  <script
    dangerouslySetInnerHTML={{
      __html: conf,
    }}
  />
  <script src="/scripts/myfile.js" />
  <script src={pageConfig.third_party_script_url} />
</Head>

When I inspect the <head> tag in Chrome everything looks right. However nothing runs and I got the error Did not expect server HTML to contain a <div> in <div>. After compiling the first load works. Refreshes fail. Not sure why it's rendering differently on server than client.

4
  • check this - see if it solves your problem: stackoverflow.com/questions/55165852/… Commented Aug 2, 2021 at 14:25
  • 2
    For the last part: stackoverflow.com/a/66777286/11613622 Commented Aug 2, 2021 at 14:54
  • Cool testing this all out in a minute. If the first comment doesn't work I can use the second :) Commented Aug 2, 2021 at 15:12
  • @SteveTomlin funny issue. I am updating question with some details now Commented Aug 2, 2021 at 15:22

1 Answer 1

1

Writing an answer here for people that might not realize some timing issues that can arise with Next.JS implement external ".js" with <script>. My third party script manipulated the DOM. So sometimes it would do that before/after React detects DOM differences from server. The full solution was to use <script> tags in <Head> for my own scripts that just put configuration for the third party script. I kept the third party <script>s out of <Head> so they would be rendered at bottom of page after everything else ran.

Sign up to request clarification or add additional context in comments.

1 Comment

Timing issues were fixed by the new next/script component. It ensures that scripts with the same strategy are loaded in order (and beforeInteractive scripts are run before afterInteractive and lazyOnload scripts). So, you could have just done --- <Script src="your script" strategy="beforeInteractive" /><Script src="third party script" /> --- by default the strategy is afterInteractive i.e. scripts are injected on the client-side and will run after hydration. Note that you have to put next/script outside next/head.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.