Vize

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.

Open the interactive example

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
Load a third-party widget on demand: initial state
Initial state
Load a third-party widget on demand: state after the verified interactions
After the verified interactions

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.