Next.js external Script onLoad quirk in Head

Sometimes it’s necessary to load external JavaScript into a React/Next.js system. There are various ways of doing this, but one of the most commonly recommended is via Next.js’s <Script /> component. Today I discovered a strange quirk. If you load the script inside a Next.js <Head /> component, then the onLoad function must be a conventional JavaScript onload function, not a React function. If you try to use a React function, it will not run, but there will be no warnings. Doubtless there are reasons for this, but it’s quite confusing considering that the first example in the Next.js documentation loads the script inside <Head />, but there’s no mention of this behaviour.

This works:

<>
  <Head>
    <title>Works!</title>
  </Head>
  <Script
    src='/path/to/script.js'
    onLoad={() => { console.log('working'); }}
  />
</>

This doesn’t work:

<>
  <Head>
    <title>Doesn't work</title>
    <Script
      src='/path/to/script.js'
      onLoad={() => { console.log('not working'); }}
    />
  </Head>
</>

This also works, but is probably not what you want since you can’t easily use it to access data inside the React stack:

<>
  <Head>
    <title>Works, sort of</title>
    <Script
      src='/path/to/script.js'
      onload='console.log("working, ish");'
    />
  </Head>
</>

References:

Add new comment

CAPTCHA