New Launch

Take a deep dive into the fastest Gatsby, yet: Gatsby 5!

Gatsby Script API

Examples

  • Using Gatsby Script

Support for the Gatsby Script API was added in gatsby@4.15.0.

Gatsby includes a built-in <Script> component that aids in loading scripts performantly.

It offers a convenient way to declare different loading strategies, and a default loading strategy that gives Gatsby users strong performance out of the box. It supports both scripts with sources and inline scripts.

Whether you want to leave the heavy lifting of managing scripts to Gatsby or you want maxiumum flexibility and control, the Gatsby <Script> component is a great tool for the job.

Using Gatsby Script in your site

Here is an example of how you can import and use the <Script> component in your site’s JSX or TSX source files:

If you have existing scripts, using the Gatsby <Script> component is as simple as importing Script and changing lowercase script tag names to capitalized Script tag names in most cases:

By default, the <Script> component will load your script after hydration. For more information on declaring loading strategies, see the Strategies section.

Scripts with sources and inline scripts

There are two types of scripts that you can tell the <Script> component to load:

  • Scripts with sources
  • Inline scripts

Scripts with sources

Scripts with sources provide a src property like this:

The <Script> component will use the value of src to deduplicate loading, so if you include two scripts on the same page with the same src, only one will load.

If for some reason you need to load two scripts with the same sources on the same page, you can provide an optional, unique id property to each and the <Script> component will attempt to load both:

Inline scripts

Inline scripts must include a unique id property and can be defined in two ways:

Here’s a look at both:

Functionally, both of these ways of defining inline scripts are equivalent.

Strategies

You can declare a loading strategy by passing a strategy property. These are the available loading strategies:

Here’s how you can define these strategies in the <Script> component:

Additionally, Gatsby exports a ScriptStrategy enum that you can use in TSX files if you prefer:

Post hydrate strategy (default)

The post-hydrate strategy is the default loading strategy and will be used if you do not specificy a strategy attribute.

The advantage of this strategy is that you have the ability to declare that your script should start loading after hydration. This is impactful because hydration is what makes your page interactive, and by using regular <script> tags (even with async or defer applied), you run the risk of your script being loaded in parallel with the framework JavaScript that hydrates your page.

This can have negative implications for key web vital metrics like Total Blocking Time. By leveraging the <Script> component with the post-hydrate strategy, you ensure that your script avoids interfering with your page reaching an interactive state, resulting in a better experience for your users.

The post-hydrate strategy is ideal for cases where you want to make sure a script loads early without impacting your site’s time to interactive.

Idle strategy

The idle strategy is similar to post-hydrate in that it loads after hydration, with the difference being idle will tell the browser to load the script when the main thread is free.

This means that if your page is doing other crucial work such as DOM manipulations or other calculations that occupy the main thread, your script will wait until after that work is complete to start loading.

The idle strategy is ideal for cases where you want to ensure a script loads in a way that does not compete with other work being done on the main thread.

Off main thread strategy (experimental)

The off-main-thread strategy, unlike post-hydrate and idle, loads your script in a web worker via Partytown.

This means that the burden of evaluation of your script is no longer the concern of the main thread, freeing it up to take care of other crucial tasks.

Note - Due to Partytown’s status as beta software, the off-main-thread strategy is considered experimental. It is subject to certain limitations and may require more configuration than other loading strategies depending on your use case.

Here is an example configuring the <Script> component with the off-main-thread strategy to load Google Analytics:

Forward collection

Gatsby will collect all off-main-thread scripts on a page, and automatically merge any Partytown forwarded events defined via the forward property into a single configuration for each page:

The forward property is the only Partytown-specific property that is handled by the <Script> component.

Proxy configuration

All URLs provided to the Gatsby <Script> component with the off-main-thread strategy are proxied by Gatsby to /__third-party-proxy?url=${YOUR_URL}.

The reason for this is many third-party scripts require a proxy to work in Partytown, so Gatsby includes built-in proxy functionality to make this easier.

To keep the proxy secure, you must define the absolute URLs you want proxied in your Gatsby config with the partytownProxiedURLs key. If you do not do this, the the request will 404.

Here’s how you would do that for the Google Analytics example above:

This works out of the box when running your site via gatsby develop, gatsby serve and Gatsby Cloud.

Hosting on other providers requires support for Gatsby’s createRedirect action to rewrite requests from /__third-party-proxy?url=${YOUR_URL} to YOUR_URL with a 200 status code. You may need to check with your hosting provider to see if this is supported.

Resolving URLs

You can leverage Partytown’s vanilla config to handle Partytown-specific behavior in your off-main-thread scripts. One such option is resolveUrl, which allows you to modify URLs handled by Partytown.

One example of a use case for resolveUrl is when using tag manager scripts such as Google Tag Manager. These scripts are challenging to use with Partytown since they contain other scripts that make other requests that may or may not need to be proxied depending on the CORS setting. In this scenario you can use resolveUrl to handle those child script URLs.

Here’s an example using Google Tag Manager to load Google Analytics (Universal Analytics in this case):

Note - This assumes you have set up Google Tag Manager to use Universal Analytics in the Google Tag Manager web application.

First you load your Google Tag Manager (GTM) script and send an initialization event:

Then you define resolveUrl in Partytown’s vanilla config to handle the Google Analytics script loaded by Google Tag Manager:

Lastly, you need to add the Google Analytics URL to partytownProxiedURLs so that Gatsby knows the URL is safe to proxy:

At this point both your Google Tag Manager and Google Analytics scripts should load successfully in your site.

Debugging

You can also leverage Partytown’s vanilla config to enable debug mode for your off-main-thread scripts:

You may need to adjust your dev tools to the verbose log level in order to see the extra logs in your console.

Limitations

By leveraging Partytown, scripts that use the off-main-thread strategy must also be aware of the limitations mentioned in the Partytown documentation. While the strategy can be powerful, it may not be the best solution for all scenarios.

In addition, there are other limitations that require upstream changes from Partytown to enable:

Usage in Gatsby SSR and Browser APIs

The Gatsby <Script> component can also be used in the following Gatsby SSR and Gatsby Browser APIs:

  • wrapPageElement
  • wrapRootElement

Note - If you use one of these APIs, it is recommended that you implement it both in Gatsby SSR and Gatsby Browser. A common pattern is to define a single function that you import and use in both files.

Here’s an example using wrapPageElement in both Gatsby SSR and Gatsby Browser without duplicating your code:

onLoad and onError callbacks

Scripts with sources loaded with the post-hydrate or idle strategies have access to two callbacks:

  • onLoad - Called once the script has loaded
  • onError - Called if the script failed to load

Note - Inline scripts and scripts using the off-main-thread strategy do not support the onLoad and onError callbacks.

Here is an example using the callbacks:

Duplicate scripts (scripts with the same id or src attributes) will execute onLoad and onError callbacks despite not being injected into the DOM.

Loading scripts dependently

Access to the onLoad and onError callbacks also enables the ability to load scripts dependently. Here’s an example showing how to load the second script after the first:

Edit this page on GitHub
© 2022 Gatsby, Inc.