useScript()
The useScript
composable provides an enhanced developer experience for loading third-party scripts with intelligent defaults for performance, security, and lifecycle management.
Basic Usage
import { useScript } from 'unhead'
const { onLoaded } = useScript('https://example.com/script.js')
onLoaded(() => {
// Script loaded successfully
console.log('Script is ready to use')
})
Smart Defaults
A singleton pattern is implemented so scripts with the same src
or key
are only loaded once globally. This helps prevent duplicate script loading and ensures consistent initialization.
The following defaults are applied for optimal performance and security:
- Scripts load after hydration by default
defer
enabled for proper execution orderfetchpriority="low"
to prioritize critical resourcescrossorigin="anonymous"
prevents cookie accessreferrerpolicy="no-referrer"
blocks referrer headers
Input Options
Simple URL
Pass a URL string for the quickest implementation:
import { useScript } from 'unhead'
useScript(unheadInstance, 'https://example.com/script.js')
Full Configuration
Pass an options object to customize any <script>
attribute:
import { useScript } from 'unhead'
useScript(unheadInstance, {
src: 'https://example.com/script.js',
id: 'my-script',
async: true,
defer: false,
crossorigin: false, // disable crossorigin='anonymous'
// Any valid script attribute can be used
})
Loading Control
Fine-tune when and how scripts load with the second parameter:
import { useScript } from 'unhead'
useScript(unheadInstance, 'https://example.com/script.js', {
// When to load the script
trigger: 'client', // | 'server' | Promise | ((load) => void)
// Resource hint strategy
warmupStrategy: 'preload', // | 'prefetch' | 'preconnect' | 'dns-prefetch',
// Access the script's API
use: () => window.externalAPI
})
Loading Triggers
Control precisely when scripts load with different trigger strategies:
import { useScript } from 'unhead'
// Load immediately on the client (default)
useScript(srcunheadInstance, , { trigger: 'client' })
// Load during server rendering
useScript(srcunheadInstance, , { trigger: 'server' })
// Load when a promise resolves
useScript(srcunheadInstance, , {
trigger: new Promise(resolve =>
setTimeout(resolve, 3000)
)
})
// Custom load function
useScript(srcunheadInstance, , {
trigger: (load) => {
document.getElementById('load-button').addEventListener('click', load)
}
})
Script Lifecycle
The script passes through these lifecycle states:
awaitingLoad
- Initial stateloading
- Script is loadingloaded
- Script loaded successfullyerror
- Script failed to loadremoved
- Script was removed
Monitor these states with lifecycle hooks:
import { useScript } from 'unhead'
const script = useScript('https://example.com/script.js')
script.onLoaded((api) => {
// Script loaded successfully
console.log('Script is ready')
})
script.onError(() => {
// Script failed to load
console.error('Script loading failed')
})
Resource Hints
The warmupStrategy
option automatically adds resource hints to optimize loading:
import { useScript } from 'unhead'
useScript(unheadInstance, 'https://example.com/script.js', {
// Preload - highest priority, load ASAP
warmupStrategy: 'preload',
// Prefetch - load when browser is idle
warmupStrategy: 'prefetch',
// Preconnect - setup connection early
warmupStrategy: 'preconnect',
// DNS Prefetch - resolve DNS early
warmupStrategy: 'dns-prefetch'
})
- Use
preload
for essential scripts needed soon after page load - Use
prefetch
for scripts needed later in the user journey - Use
preconnect
ordns-prefetch
to optimize third-party domains
API Proxying
If you need to access the script's API before it loads, use the use
option with proxy support:
import { useScript } from 'unhead'
const script = useScript({
src: 'https://maps.googleapis.com/maps/api/js'
}, {
use: () => window.google.maps
})
// Works before script loads!
const map = script.proxy.Map()
The proxy records all calls and replays them once the script is loaded, allowing you to use the API immediately in your code without worrying about loading state.
Common Use Cases
Google Analytics
import { useScript } from 'unhead'
useScript(unheadInstance, {
src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX',
async: true
}, {
trigger: 'client'
})
// Initialize gtag
useHead(unheadInstance, {
script: [
{
children: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
`,
key: 'gtag-config'
}
]
})
Loading on User Interaction
import { useScript } from 'unhead'
// Load YouTube player only when user clicks play
useScript(unheadInstance, 'https://www.youtube.com/iframe_api', {
trigger: (load) => {
document.getElementById('play-video').addEventListener('click', () => {
load()
// Show loading indicator while script is loading
})
}
})
API Reference
Input
src
: String URL or object with script attributes
Options
trigger
: When to load the script ('client', 'server', Promise, or custom function)warmupStrategy
: Resource hint strategy ('preload', 'prefetch', 'preconnect', 'dns-prefetch')use
: Function to access the script's API
Return Value
Returns a script controller object with these properties:
status
: Current lifecycle stateonLoaded
: Register callback for successful loadonError
: Register callback for loading failureproxy
: Proxy to the script's API (ifuse
option provided)