use-user-activation
Track sticky and transient user activation with the User Activation API.
| Package | @vizejs/composable/use-user-activation |
| Own the source | vize lib pull composable:use-user-activation |
| Runtime exports | useUserActivation |
| Gzip budget | 2048 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 { useUserActivation } from "@vizejs/composable/use-user-activation";
Try it
Wait for the first interaction
Know whether the reader has interacted with the page before using APIs that require it.
What to observe: The message changes after the first click or key press anywhere on the page.
Browsers require user activation for audio, popups and some permissions. isActive reports transient activation.
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 { useUserActivation } from "@vizejs/composable/use-user-activation";
const { hasBeenActive } = useUserActivation();
</script>
<template>
<div class="composable-example">
<p>Wait for the reader's first interaction before playing sound or opening a popup.</p>
<button type="button">Interact with the page</button>
<output aria-live="polite">{{
hasBeenActive ? "The page may now play sound." : "Waiting for the first interaction."
}}</output>
</div>
</template>
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useUserActivation |
input | experimental | deterministic-fallback | caller-managed | caller, reactive-scope | web, desktop | window |
tryOnScopeDispose |
API
useUserActivation
Track sticky and transient user activation with the User Activation API. The state is refreshed on activation-triggering events of target (immediately and again after a microtask) and polled while isActive is true so its expiry is observed. Listeners and the timer are removed when the owning reactive scope stops; outside a scope call stop(). Server rendering: no listeners or timers, supported, hasBeenActive, and isActive are false.
function useUserActivation(options: UseUserActivationOptions = {}): UserActivationControls
const { isActive } = useUserActivation();
const canOpenPopup = computed(() => isActive.value);
Types
UserActivationLike
Minimal navigator.userActivation (UserActivation).
| Member | Type | Description |
|---|---|---|
hasBeenActive |
boolean |
Whether the page ever had sticky activation. |
isActive |
boolean |
Whether the page currently has transient activation. |
UseUserActivationOptions
Options for useUserActivation.
| Member | Type | Description |
|---|---|---|
userActivation? |
MaybeRefOrGetter<UserActivationLike | null | undefined> |
User activation state for alternate runtimes and tests. |
target? |
MaybeRefOrGetter<EventTarget | null | undefined> |
Target whose activation-triggering events refresh the state. |
events? |
readonly string[] |
Events that refresh the state. |
interval? |
number |
Poll interval in milliseconds while isActive is true, so its expiry is observed. 0 disables polling. |
scheduler? |
IntervalScheduler |
Timer host for polling. |
UserActivationControls
Reactive state returned by useUserActivation.
| Member | Type | Description |
|---|---|---|
supported |
ComputedRef<boolean> |
Whether the User Activation API is available. |
hasBeenActive |
Readonly<Ref<boolean>> |
Sticky activation: the user interacted with the page at least once. |
isActive |
Readonly<Ref<boolean>> |
Transient activation: a gated API (popup, fullscreen, clipboard) may be called now. |
refresh |
() => void |
Re-read the activation state. |
stop |
() => void |
Remove listeners and timers. Idempotent. |