Guides

Key Concepts

Learn about the key concepts of Nuxt Scripts.

The useScript composable is the core of Nuxt Scripts and is used to load all scripts.

There are additional layers of abstraction built on top of useScript to make it easier to load scripts in different ways.

  1. Registry Scripts - Preconfigured third-party scripts that can be loaded through Nuxt Config, composables and components.
  2. Global Scripts - Load scripts through your Nuxt Config file.

Unhead Abstraction

The Nuxt Scripts useScript composable is an abstraction of Unhead's useScript, which in turn is an abstraction on top of useHead. Many of the features available to you through useHead are also available in Nuxt Scripts useScript.

Script Singleton

With Nuxt Scripts, it's not possible to load a script with the same src (or key) multiple times. This is because the script is loaded globally and is shared across all components.

This means that a script will only go through the initialization process once, and any subsequent calls to useScript will return the same instance.

For this reason, you may consider wrapping your useScript calls in their own composable to allow for easier instantiation of the script.

useMyScript.ts
export function useMyScript() {
  return useScript({
    src: 'https://example.com/script.js',
  })
}

Default Behavior

Nuxt Scripts does not insert script tags within the SSR response. This is a performance decision to minimise the interruptions to the hydration process. Instead, scripts are loaded by default when Nuxt is fully hydrated on the client side.

You can change this behavior by modifying the defaultScriptOptions.

Nuxt Scripts will also insert several extra tags to the script element to help with performance and privacy.

  • async - Scripts are loaded asynchronously to prevent blocking the rendering of the page.
  • defer - Scripts are deferred to ensure they are executed in the order they are loaded.
  • crossorigin="anonymous" - Scripts are loaded with the anonymous attribute to prevent them from accessing cookies.
  • referrerpolicy="no-referrer" - Scripts are loaded with the no-referrer policy to prevent them from sending the referrer header.

Understanding proxied functions

You may wonder how the useScript composable can return SSR safe functions that can be called before the script is loaded.

const { proxy } = useScript('/script.js')
// just works as you'd expect - magic?
proxy.gtag('event', 'page_view')

The gtag function call is a proxy that queues the function to be called when the script is loaded. If the script never loads then the function is never called.

This has several benefits:

  • SSR safe
  • Won't break your site if the script never loads (blocked by adblockers)
  • Allows you to load the script whenever you want without worrying about the order of the script and function calls

But it also has some downsides:

  • It only works for functions where you don't need the return value. You can await the function call to get the return value, but this will block the rendering of the page.
  • It can be confusing to debug if you're not aware of how it works.

It's recommended to await the script load if you want to access the script's API directly.

const { onLoaded } = useScript('/script.js')
// use the script instance directly, not proxied
onLoaded(({ gtag }) => {
  gtag('event', 'page_view')
})