--- title: useScript() description: A powerful API for loading third-party scripts with optimized performance new: true --- The `useScript` composable provides an enhanced developer experience for loading third-party scripts with intelligent defaults for performance, security, and lifecycle management. ## Basic Usage ```ts import { useScript } from '@unhead/dynamic-import' 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`{lang="html"} enabled for proper execution order - `fetchpriority="low"`{lang="html"} to prioritize critical resources - `crossorigin="anonymous"`{lang="html"} prevents cookie access - `referrerpolicy="no-referrer"`{lang="html"} blocks referrer headers ## Input Options ### Simple URL Pass a URL string for the quickest implementation: ```ts import { useScript } from '@unhead/dynamic-import' useScript('https://example.com/script.js') ``` ### Full Configuration Pass an options object to customize any `<script>`{lang="html"} attribute: ```ts import { useScript } from '@unhead/dynamic-import' useScript({ 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: ```ts import { useScript } from '@unhead/dynamic-import' useScript('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: ```ts import { useScript } from '@unhead/dynamic-import' // Load immediately on the client (default) useScript(src, { trigger: 'client' }) // Load during server rendering useScript(src, { trigger: 'server' }) // Load when a promise resolves useScript(src, { trigger: new Promise(resolve => setTimeout(resolve, 3000) ) }) // Custom load function useScript(src, { trigger: (load) => { document.getElementById('load-button').addEventListener('click', load) } }) ``` ## Script Lifecycle The script passes through these lifecycle states: - `awaitingLoad` - Initial state - `loading` - Script is loading - `loaded` - Script loaded successfully - `error` - Script failed to load - `removed` - Script was removed Monitor these states with lifecycle hooks: ```ts import { useScript } from '@unhead/dynamic-import' 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: ```ts import { useScript } from '@unhead/dynamic-import' useScript('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' }) ``` ::tip Choose the right strategy based on how critical the script is: - Use `preload` for essential scripts needed soon after page load - Use `prefetch` for scripts needed later in the user journey - Use `preconnect` or `dns-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: ```ts import { useScript } from '@unhead/dynamic-import' 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 ```ts import { useScript } from '@unhead/dynamic-import' useScript({ src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX', async: true }, { trigger: 'client' }) // Initialize gtag useHead({ 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 ```ts import { useScript } from '@unhead/dynamic-import' // Load YouTube player only when user clicks play useScript('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 state - `onLoaded`: Register callback for successful load - `onError`: Register callback for loading failure - `proxy`: Proxy to the script's API (if `use` option provided)