use-script-tag
Inject a <script> tag and track its loading state.
| Package | @vizejs/composable/use-script-tag |
| Own the source | vize lib pull composable:use-script-tag |
| Runtime exports | useScriptTag |
| Gzip budget | 2816 B |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/composable
Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.
import { useScriptTag } from "@vizejs/composable/use-script-tag";
Try it
Load a third-party widget on demand
Load an external script only when the reader asks for it, and report its status.
What to observe: Load widget moves the status from idle through loading to loaded. Remove widget removes the script tag.
Use integrity and crossOrigin for third-party scripts. The example uses a data URL so the docs need no network access.
Compare the initial and interacted states


Copy the example
Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.
<script setup lang="ts">
import { useScriptTag } from "@vizejs/composable/use-script-tag";
// Point this at a real third-party widget in your app.
const widget =
"data:text/javascript,window.exampleWidget%20%3D%20%7B%20version%3A%20%222.1%22%20%7D%3B";
const { status, load, unload } = useScriptTag(widget, { immediate: false });
</script>
<template>
<div class="composable-example">
<p>Load a third-party script only when the reader asks for the widget.</p>
<div class="example-actions">
<button type="button" :disabled="status === 'loaded'" @click="() => load()">
Load widget
</button>
<button type="button" :disabled="status !== 'loaded'" @click="() => unload()">
Remove widget
</button>
</div>
<output aria-live="polite">Script status: {{ status }}</output>
</div>
</template>
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useScriptTag |
dom | experimental | deterministic-fallback | caller-managed | caller, reactive-scope | web, desktop | window |
tryOnScopeDispose |
API
useScriptTag
Inject a <script> tag and track its loading state. An existing tag with the same src is reused instead of duplicated: if it was created by another useScriptTag call its state is shared through a data-vize-script-status attribute; a tag without that attribute (for example emitted in server-rendered HTML) is assumed to have executed. Changing the reactive src unloads the previous script and, with immediate, loads the new one. Server rendering: no document exists, so nothing is injected, status stays "idle", and load resolves "unsupported". Emit server-side script tags through the application's head manager. Scripts created by this composable are removed when the owning scope stops (configurable); already-executed code cannot be unloaded.
function useScriptTag( src: MaybeRefOrGetter<string>, options: UseScriptTagOptions = {}, ): ScriptTagControls
const { status } = useScriptTag("https://example.com/widget.js", {
onLoaded: () => window.Widget.init(),
});
Types
ScriptTagElement
<script> subset used by useScriptTag.
| Member | Type | Description |
|---|---|---|
getAttribute |
(name: string) => string | null |
Read an attribute. |
setAttribute |
(name: string, value: string) => void |
Write an attribute. |
ScriptTagHost
Document capability used by useScriptTag.
| Member | Type | Description |
|---|---|---|
findScript |
(src: string) => ScriptTagElement | undefined |
Find an existing <script> whose src attribute equals src. |
createScript |
() => ScriptTagElement |
Create a detached <script>. |
append |
(element: ScriptTagElement) => void |
Attach a script to <head>, starting its download. |
remove |
(element: ScriptTagElement) => void |
Detach a script. |
UseScriptTagOptions
Options for useScriptTag.
| Member | Type | Description |
|---|---|---|
onLoaded? |
(element: ScriptTagElement) => void |
Called once the script has loaded. |
immediate? |
boolean |
Load when created and whenever src changes. |
async? |
boolean |
Set the async attribute. |
defer? |
boolean |
Set the defer attribute. |
type? |
string |
Script type (for example "module"). |
crossOrigin? |
"anonymous" | "use-credentials" |
CORS mode (crossorigin attribute). |
referrerPolicy? |
ReferrerPolicy |
Referrer policy. |
noModule? |
boolean |
Set the nomodule attribute. |
nonce? |
string |
CSP nonce. |
integrity? |
string |
Subresource integrity hash. |
attributes? |
Readonly<Record<string, string>> |
Additional attributes. |
removeOnDispose? |
boolean |
Remove a script created by this composable when the owning scope stops. |
host? |
MaybeRefOrGetter<ScriptTagHost | null | undefined> |
Document capability for alternate runtimes and tests. |
ScriptTagControls
Reactive state and actions returned by useScriptTag.
| Member | Type | Description |
|---|---|---|
status |
Readonly<Ref<ScriptTagStatus>> |
Loading state. |
element |
Readonly<ShallowRef<ScriptTagElement | undefined>> |
Script element in use, if any. |
load |
() => Promise<ScriptTagResult> |
Load the script (or reuse an existing tag with the same src). Concurrent calls share one load; unload and scope disposal resolve a pending load as "cancelled". |
unload |
() => void |
Remove a script created by this composable and reset the state. |