Overview

The Script component is an extension of the HTML <script> tag that allows you to control the loading priority of scripts.

Import

🚧

IMPORTANT

For local environment setup, make sure you are using Next.js 11.0.0 or later.

The Script component can be imported directly from the Frontend Components package, which is pre-installed in your Shogun Frontend store.

import { Script } from '@getshogun/frontend-components'

Props

nametypedefault valuedescription
strategybeforeInteractive | afterInteractive | lazyOnload | workerafterInteractiveDetermine when the script should be load. See the Usage section below for more information.
onLoad() => {}A function to be executed after the script is finished loading. See the Usage section below for more information.

📘

In addition to the props above, Script accepts any other DOM attribute you pass to it.

Usage

Basic usage

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  return (
    <>
      <Script src="https://www.example.com/some-script.js" />
    </>
  )
}

export default Home

strategy usage

To control when the script should be loaded, use the strategy prop.

beforeInteractive

By using strategy="beforeInteractive" the script will be loaded before the page is fully loaded (interactive). Scripts using this approach are injected into the initial HTML markup from the server, and executed before the JavaScript bundle.

📘

This strategy should be used for any critical scripts that need to be fetched and executed before the page is interactive.

⚠️ Please avoid using this strategy for every script, as it will increase the time for the page to become interactive, causing a bad user experience.

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  return (
    <>
      <Script
        src="https://www.example.com/some-script.js"
        strategy="beforeInteractive"
      />
    </>
  )
}

export default Home

afterInteractive

By using strategy="afterInteractive", the script will be loaded immediately after the page becomes interactive. This strategy is ideal for scripts that don't need to be loaded before the page is interactive, such as analytics scripts.

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  return (
    <>
      <Script
        strategy="afterInteractive"
        dangerouslySetInnerHTML={{
          __html: `
          (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
          new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
          j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
          'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
          })(window,document,'script','dataLayer', 'GTM-XXXXXX');
        `,
        }}
      />
    </>
  )
}

export default Home

lazyOnload

By using strategy="lazyOnload", the script will be loaded after all the page's resources have been fetched. This strategy is ideal for scripts that can be executed in the background, such as chat and social media widgets.

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  return (
    <>
      <Script
        src="https://www.example.com/some-script.js"
        strategy="lazyOnload"
      />
    </>
  )
}

export default Home

onLoad usage

The onLoad prop allow you to execute scripts after a script is fully fetched and loaded.

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  const [state, setState] = useState(null)

  return (
    <>
      <Script
        src="https://www.example.com/some-script.js"
        onLoad={() => {
          setState({ hello: 'world' })
        }}
      />
    </>
  )
}

export default Home

worker

🚧

WARNING

The worker strategy experimental, and can cause unexpected issues in your application. Use it with caution, and test it properly before publishing.

You might want to use other strategies instead. The Script component supports:

  • beforeInteractive: Load before the page is interactive.
  • afterInteractive: (default) Load immediately after the page becomes interactive.
  • lazyOnload: Load during idle time.

By using strategy="worker", the script will be loaded on a separate worker thread using Partytown. This strategy is ideal for third party scripts that have minimal interaction with the UI like Google Analytics and Facebook Pixel.

See here to understand the tradeoffs of using Partytown.

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  return (
    <>
      <Script
        src="https://www.example.com/some-script.js"
        strategy="worker"
      />
    </>
  )
}

export default Home
Illustration from Partytown showing how the scripts would be executed using the worker thread.Illustration from Partytown showing how the scripts would be executed using the worker thread.

Illustration from Partytown showing how the scripts would be executed using the worker thread.

📘

Partytown config

Editing the Partytown config is currently not possible through the Shogun Frontend application. To include your custom config object contact Shogun Support.

Example custom config:

{ debug: true, forward: [‘dataLayer.push’] }

See here for the full list of options.

Inline Scripts

🚧

Limitations

  • An id attribute must be defined.
  • Only the afterInteractive and lazyOnload strategies can be used.

You can inline scripts that aren't loaded from an external file:

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  const [state, setState] = useState(null)

  return (
    <>
      <Script id="my-script" strategy="lazyOnload">
        {`document.getElementById('banner').classList.remove('hidden')`}
      </Script>
    </>
  )
}

export default Home

with dangerouslySetInnerHTML

It's also possible to use dangerouslySetInnerHTML to achieve the same as the previous example:

import React from 'react'
import { Script } from '@getshogun/frontend-components'

const Home = () => {
  const [state, setState] = useState(null)

  return (
    <>
      <Script
        id="my-script"
        strategy="lazyOnload"
        dangerouslySetInnerHTML={{
          __html: `document.getElementById('banner').classList.remove('hidden')`
        }}
      >
    </>
  )
}

export default Home