Key Concepts
The useScript() composable is the core of Nuxt Scripts and loads all scripts.
Nuxt Scripts provides additional layers of abstraction built on top of useScript() to make it easier to load scripts in different ways.
- Registry Scripts - Preconfigured third-party scripts that load through Nuxt Config, composables and components.
- 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, you cannot load a script with the same src (or key) multiple times because the script loads globally and all components share it.
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.
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 performance decision minimizes interruptions to the hydration process. Instead, Nuxt loads scripts by default when fully hydrated on the client side.
You can change this behavior by modifying the defaultScriptOptions.
Nuxt Scripts also inserts several extra tags to the <script> element to optimize performance and privacy.
async- Nuxt loads scripts asynchronously to prevent blocking page rendering.defer- Nuxt defers scripts to ensure they execute in their loading order.crossorigin="anonymous"- Nuxt loads scripts with theanonymousattribute to prevent cookie access.referrerpolicy="no-referrer"- Nuxt uses theno-referrerpolicy to prevent sending the referrer header.fetchpriority="low"- Nuxt loads scripts with lower priority to improve performance.
Note:
asyncdoes not apply by default because the module usesdefer. If you needasync, you can explicitly disabledefer.
Understanding proxied functions
You may wonder how the useScript() composable can return SSR safe functions that you can call before the script loads.
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 call when the script loads. If
the script never loads then the function never executes.
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 script and function call order
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 blocks rendering.
- Debugging may be confusing if you're not aware of how it works.
We recommend awaiting 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')
})