📄 useScriptTag¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 5 |
| 📦 Imports | 10 |
| ⚡ Async/Await Patterns | 2 |
| 📐 Interfaces | 2 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/core/useScriptTag/index.ts
📦 Imports¶
| Name | Source |
|---|---|
MaybeRefOrGetter |
vue |
ShallowRef |
vue |
ConfigurableDocument |
../_configurable |
noop |
@vueuse/shared |
tryOnMounted |
@vueuse/shared |
tryOnUnmounted |
@vueuse/shared |
shallowRef |
vue |
toValue |
vue |
defaultDocument |
../_configurable |
useEventListener |
../useEventListener |
Async/Await Patterns¶
| Type | Function | Await Expressions | Promise Chains |
|---|---|---|---|
| promise-chain | useScriptTag |
none | new Promise(...) |
| promise-chain | loadScript |
none | new Promise(...) |
Functions¶
useScriptTag(src: MaybeRefOrGetter<string>, onLoaded: (el: HTMLScriptElement) => void, options: UseScriptTagOptions): UseScriptTagReturn¶
Async script tag loading.
Parameters:
srcany: No descriptiononLoadedany: No descriptionoptionsany: No description
See: https://vueuse.org/useScriptTag
Raw JSDoc
Calls:
shallowRef (from vue)resolvedocument.querySelectortoValue (from vue)document.createElementObject.entries(attrs).forEachel?.setAttributeel.hasAttributeresolveWithElementuseEventListener (from ../useEventListener)rejectel!.setAttributeonLoadeddocument.head.appendChildloadScriptdocument.head.removeChildtryOnMounted (from @vueuse/shared)tryOnUnmounted (from @vueuse/shared)
Internal Comments:
/**
* Load the script specified via `src`.
*
* @param waitForScriptLoad Whether if the Promise should resolve once the "load" event is emitted by the <script> attribute, or right after appending it to the DOM.
* @returns Promise<HTMLScriptElement>
*/ (x2)
// Some little closure for resolving the Promise. (x2)
// Check if document actually exists, otherwise resolve the Promise (SSR Support).
// Local variable defining if the <script> tag should be appended or not. (x2)
// Script tag not found, preparing the element for appending
// Optional attributes
// Enables shouldAppend (x3)
// Event listeners (x2)
// Append the <script> tag to head.
// If script load awaiting isn't needed, we can resolve the Promise.
/**
* Exposed singleton wrapper for `loadScript`, avoiding calling it twice.
*
* @param waitForScriptLoad Whether if the Promise should resolve once the "load" event is emitted by the <script> attribute, or right after appending it to the DOM.
* @returns Promise<HTMLScriptElement>
*/ (x2)
/**
* Unload the script specified by `src`.
*/ (x2)
Code
export function useScriptTag(
src: MaybeRefOrGetter<string>,
onLoaded: (el: HTMLScriptElement) => void = noop,
options: UseScriptTagOptions = {},
): UseScriptTagReturn {
const {
immediate = true,
manual = false,
type = 'text/javascript',
async = true,
crossOrigin,
referrerPolicy,
noModule,
defer,
document = defaultDocument,
attrs = {},
nonce = undefined,
} = options
const scriptTag = shallowRef<HTMLScriptElement | null>(null)
let _promise: Promise<HTMLScriptElement | boolean> | null = null
/**
* Load the script specified via `src`.
*
* @param waitForScriptLoad Whether if the Promise should resolve once the "load" event is emitted by the <script> attribute, or right after appending it to the DOM.
* @returns Promise<HTMLScriptElement>
*/
const loadScript = (waitForScriptLoad: boolean): Promise<HTMLScriptElement | boolean> => new Promise((resolve, reject) => {
// Some little closure for resolving the Promise.
const resolveWithElement = (el: HTMLScriptElement) => {
scriptTag.value = el
resolve(el)
return el
}
// Check if document actually exists, otherwise resolve the Promise (SSR Support).
if (!document) {
resolve(false)
return
}
// Local variable defining if the <script> tag should be appended or not.
let shouldAppend = false
let el = document.querySelector<HTMLScriptElement>(`script[src="${toValue(src)}"]`)
// Script tag not found, preparing the element for appending
if (!el) {
el = document.createElement('script')
el.type = type
el.async = async
el.src = toValue(src)
// Optional attributes
if (defer)
el.defer = defer
if (crossOrigin)
el.crossOrigin = crossOrigin
if (noModule)
el.noModule = noModule
if (referrerPolicy)
el.referrerPolicy = referrerPolicy
if (nonce) {
el.nonce = nonce
}
Object.entries(attrs).forEach(([name, value]) => el?.setAttribute(name, value))
// Enables shouldAppend
shouldAppend = true
}
// Script tag already exists, resolve the loading Promise with it.
else if (el.hasAttribute('data-loaded')) {
resolveWithElement(el)
}
// Event listeners
const listenerOptions = {
passive: true,
}
useEventListener(el, 'error', event => reject(event), listenerOptions)
useEventListener(el, 'abort', event => reject(event), listenerOptions)
useEventListener(el, 'load', () => {
el!.setAttribute('data-loaded', 'true')
onLoaded(el!)
resolveWithElement(el!)
}, listenerOptions)
// Append the <script> tag to head.
if (shouldAppend)
el = document.head.appendChild(el)
// If script load awaiting isn't needed, we can resolve the Promise.
if (!waitForScriptLoad)
resolveWithElement(el)
})
/**
* Exposed singleton wrapper for `loadScript`, avoiding calling it twice.
*
* @param waitForScriptLoad Whether if the Promise should resolve once the "load" event is emitted by the <script> attribute, or right after appending it to the DOM.
* @returns Promise<HTMLScriptElement>
*/
const load = (waitForScriptLoad = true): Promise<HTMLScriptElement | boolean> => {
if (!_promise)
_promise = loadScript(waitForScriptLoad)
return _promise
}
/**
* Unload the script specified by `src`.
*/
const unload = () => {
if (!document)
return
_promise = null
if (scriptTag.value)
scriptTag.value = null
const el = document.querySelector<HTMLScriptElement>(`script[src="${toValue(src)}"]`)
if (el)
document.head.removeChild(el)
}
if (immediate && !manual)
tryOnMounted(load)
if (!manual)
tryOnUnmounted(unload)
return { scriptTag, load, unload }
}
Internal helpers¶
Declared inside another function in this file.
loadScript(waitForScriptLoad: boolean): Promise<HTMLScriptElement | boolean>¶
Parameters:
waitForScriptLoadboolean
Returns: Promise<HTMLScriptElement | boolean>
Code
(waitForScriptLoad: boolean): Promise<HTMLScriptElement | boolean> => new Promise((resolve, reject) => {
// Some little closure for resolving the Promise.
const resolveWithElement = (el: HTMLScriptElement) => {
scriptTag.value = el
resolve(el)
return el
}
// Check if document actually exists, otherwise resolve the Promise (SSR Support).
if (!document) {
resolve(false)
return
}
// Local variable defining if the <script> tag should be appended or not.
let shouldAppend = false
let el = document.querySelector<HTMLScriptElement>(`script[src="${toValue(src)}"]`)
// Script tag not found, preparing the element for appending
if (!el) {
el = document.createElement('script')
el.type = type
el.async = async
el.src = toValue(src)
// Optional attributes
if (defer)
el.defer = defer
if (crossOrigin)
el.crossOrigin = crossOrigin
if (noModule)
el.noModule = noModule
if (referrerPolicy)
el.referrerPolicy = referrerPolicy
if (nonce) {
el.nonce = nonce
}
Object.entries(attrs).forEach(([name, value]) => el?.setAttribute(name, value))
// Enables shouldAppend
shouldAppend = true
}
// Script tag already exists, resolve the loading Promise with it.
else if (el.hasAttribute('data-loaded')) {
resolveWithElement(el)
}
// Event listeners
const listenerOptions = {
passive: true,
}
useEventListener(el, 'error', event => reject(event), listenerOptions)
useEventListener(el, 'abort', event => reject(event), listenerOptions)
useEventListener(el, 'load', () => {
el!.setAttribute('data-loaded', 'true')
onLoaded(el!)
resolveWithElement(el!)
}, listenerOptions)
// Append the <script> tag to head.
if (shouldAppend)
el = document.head.appendChild(el)
// If script load awaiting isn't needed, we can resolve the Promise.
if (!waitForScriptLoad)
resolveWithElement(el)
})
resolveWithElement(el: HTMLScriptElement): HTMLScriptElement¶
Parameters:
elHTMLScriptElement
Returns: HTMLScriptElement
Calls:
resolve
load(waitForScriptLoad: boolean): Promise<HTMLScriptElement | boolean>¶
Parameters:
waitForScriptLoadboolean
Returns: Promise<HTMLScriptElement | boolean>
Calls:
loadScript
Code
unload(): void¶
Returns: void
Calls:
document.querySelectortoValue (from vue)document.head.removeChild
Code
Interfaces¶
UseScriptTagOptions¶
Interface Code
export interface UseScriptTagOptions extends ConfigurableDocument {
/**
* Load the script immediately
*
* @default true
*/
immediate?: boolean
/**
* Add `async` attribute to the script tag
*
* @default true
*/
async?: boolean
/**
* Script type
*
* @default 'text/javascript'
*/
type?: string
/**
* Manual controls the timing of loading and unloading
*
* @default false
*/
manual?: boolean
crossOrigin?: 'anonymous' | 'use-credentials'
referrerPolicy?: 'no-referrer' | 'no-referrer-when-downgrade' | 'origin' | 'origin-when-cross-origin' | 'same-origin' | 'strict-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url'
noModule?: boolean
defer?: boolean
/**
* Add custom attribute to the script tag
*
*/
attrs?: Record<string, string>
/**
* Nonce value for CSP (Content Security Policy)
* @default undefined
*/
nonce?: string
}
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
immediate |
boolean |
✓ | not shown |
async |
boolean |
✓ | not shown |
type |
string |
✓ | not shown |
manual |
boolean |
✓ | not shown |
crossOrigin |
'anonymous' \| 'use-credentials' |
✓ | not shown |
referrerPolicy |
'no-referrer' \| 'no-referrer-when-downgrade' \| 'origin' \| 'origin-when-cro... |
✓ | not shown |
noModule |
boolean |
✓ | not shown |
defer |
boolean |
✓ | not shown |
attrs |
Record<string, string> |
✓ | not shown |
nonce |
string |
✓ | not shown |
UseScriptTagReturn¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
scriptTag |
ShallowRef<HTMLScriptElement \| null> |
✗ | not shown |
load |
(waitForScriptLoad?: boolean) => Promise<HTMLScriptElement \| boolean> |
✗ | not shown |
unload |
() => void |
✗ | not shown |
Generated by Syntax Scribe