useScript()
Open the live Custom Script example.
This composable wraps Unhead's useScript(), adding Nuxt triggers, bundling, proxying, and reload(). It also has an experimental Partytown path with a smaller API, described below.
Signature
export function useScript<T extends Record<symbol | string, any> = Record<symbol | string, any>>(
input: UseScriptInput,
options?: NuxtUseScriptOptions<T>,
): UseScriptContext<UseFunctionType<NuxtUseScriptOptions<T>, T>>
Arguments
UseScriptInput
Pass a URL string or an object containing script tag attributes.
export type UseScriptInput = string | {
src: string
async?: boolean
defer?: boolean
type?: string
integrity?: string
crossorigin?: string
innerHTML?: string
textContent?: string
referrerpolicy?: string
// Additional Unhead script and data attributes are supported.
}
Unhead's complete script example shows tag attributes alongside loading options.
NuxtUseScriptOptions
Nuxt Scripts extends Unhead's script triggers and warmup options with these options:
resolve- Resolve the loaded SDK with lifecycle-boundsignalandwaitForhelpers.use- Legacy synchronous or async SDK resolver. Preferresolvefor callback-based readiness.trigger- Triggering Script Loadingbundle- Control first-party bundling.proxy- Enable or disable supported collection proxying for a registry script.partytown- Run a supported registry script through Partytown.
partytown: true takes an early SSR path. It writes a <script type="text/partytown" src="…"> tag immediately, regardless of trigger, and ignores other script attributes and options such as use, beforeInit, and warmupStrategy. The returned stub reports loaded; load() is a no-op, remove() only disconnects DevTools observation, and proxy, reload(), and lifecycle callbacks are not available. Treat the Partytown return value as an implementation detail.
export type NuxtUseScriptOptions<T = any> = Omit<UseScriptOptions<T>, 'trigger'> & {
/**
* The trigger to load the script:
* - `onNuxtReady` - Load the script when Nuxt is ready.
* - `manual` - Load the script manually by calling `load()`
* - `Promise` - Load the script when the promise resolves.
*/
trigger?: UseScriptOptions<T>['trigger'] | 'onNuxtReady'
/**
* Bundle the script as an asset and serve it from your server. This avoids the
* original host's DNS lookup and keeps the initial request on your origin.
* - `true` - Bundle the script as an asset.
* - `'force'` - Bundle and download the script again instead of using the build cache.
* - `false` - Do not bundle the script. (default for plain useScript calls)
*
* @deprecated Bundling is enabled automatically for registry scripts that support it.
* Set `bundle: false` on a registry script to disable it.
*/
bundle?: boolean | 'force'
/**
* Load the script in a web worker using Partytown.
* When enabled, adds `type="text/partytown"` to the script tag.
* Requires @nuxtjs/partytown to be installed and configured separately.
* @see https://partytown.qwik.dev/
*/
partytown?: boolean
/**
* Control proxying for this script.
* When `false`, collection requests go directly to the third-party server.
* When `true`, collection requests are proxied through `/_scripts/p/`.
* This option applies to registry scripts and defaults to their declared
* `proxy` capability.
*/
proxy?: boolean
/**
* Skip schema validation for the script input. Use this for development stubs
* that do not load the actual script.
*/
skipValidation?: boolean
/**
* Specify a strategy for warming up the connection to the third-party script.
* - `false` - Disable preloading.
* - `'preload'` - Preload the script.
* - `'preconnect'` | `'dns-prefetch'` - Preconnect to the script origin.
*/
warmupStrategy?: false | 'preload' | 'preconnect' | 'dns-prefetch'
}
Return
For the base context API, see Unhead's proxy and direct-access examples. The proxied functions guide explains how calls queue before a script loads.
Outside the Partytown path, the returned object includes:
proxy- A typed proxy that queues calls until loading finishesstatus- Reactive ref with the script status:'awaitingLoad'|'loading'|'loaded'|'error'|'removed'load()- Function to manually load the scriptsignal- AnAbortSignalscoped to this composable consumerdispose()- Release this consumer's callbacks and triggers without removing the shared scriptscript- The shared Unhead script instanceremove()- Remove the shared script for every consumerreload()- Function to remove and reload the script (see below)onLoaded()andonError()- Script lifecycle callbacks
Each call receives its own consumer scope. Vue disposes that scope when its
component unmounts, while the shared script remains available to other callers.
Call remove() only to remove the script globally.
Lifecycle-aware SDK readiness
Use resolve({ waitFor }) when a vendor exposes a callback that fires
after the script element's load event. Listener cleanup and abort rejection are
then tied to the shared script lifecycle.
const sdk = useScript<{ ready: true }>('https://example.com/sdk.js', {
resolve: ({ waitFor }) => waitFor<{ ready: true }>((resolve) => {
window.onExampleReady = () => resolve({ ready: true })
return () => delete window.onExampleReady
}),
})
const api = await sdk.load()
reload()
Removes the script, inserts it again, and re-executes it. Use this for a script that scans the DOM once and must scan again after SPA navigation.
const { reload } = useScript('https://example.com/dom-scanner.js')
// Reload when navigating
watch(() => route.path, () => reload())
Prefer the vendor's SPA API when one exists. For example, iubenda's _iub.cs.api.activateSnippets() activates newly added blocked snippets without reloading the whole script.