useAddToHomescreen()

useAddToHomescreen() is the composable used internally by <SwAddToHomescreenGuide>. It encapsulates the show decision + lifecycle: UA detection, config reading, session/persistent memory, and delayed trigger. All window / navigator access lives inside onMounted + import.meta.client for SSR safety.

Application code rarely calls this directly — mounting <SwAddToHomescreenGuide /> gives you the full feature. Consume this composable directly only when you want a fully custom guide UI (skipping the framework's bottom sheet).

Show Decision (all conditions must hold for open=true)

The probe below shows how your current environment evaluates against each gate (desktop browsers usually stop at gate ④):

Gate probe for current environment

加载中...
  1. Client environment (import.meta.client)
  2. PWA enabled (runtimeConfig.public.swiftWebFramework.pwa.enabled)
  3. addToHomescreen not explicitly disabled
  4. Not in standalone mode (user hasn't added the site to home screen)
  5. UA unambiguously identifies iOS Safari or Android mainstream Chromium browser
  6. User hasn't been "remembered as dismissed" recently (per rememberFor)

Basic Usage

<script setup lang="ts">
const { open, platform, dismiss } = useAddToHomescreen({
  delay: 2000,
  rememberFor: 'session',
})
</script>

<template>
  <Teleport to="body">
    <div v-if="open" class="my-custom-guide">
      <p v-if="platform === 'ios'">Safari toolbar → Share → Add to Home Screen</p>
      <p v-else-if="platform === 'android'">Top-right menu → Add to Home Screen</p>
      <button @click="dismiss">Close</button>
    </div>
  </Teleport>
</template>

Options

useAddToHomescreen({
  delay: 3000,        // Optional. Defaults to runtimeConfig or 2000
  rememberFor: '7d',       // Optional. Defaults to runtimeConfig or 'session'
})
OptionTypeDefaultDescription
delaynumber2000Milliseconds after mount before showing. Priority: option > runtimeConfig > 2000
rememberFor'session' | PeriodSpec'session'Memory strategy. 'session' = sessionStorage; 'Nm'·'Nh'·'Nd' = N days via localStorage; 0/negative = no memory
trackInstall{ traceId?: string }undefinedPWA install tracking (opt-in): when provided, listens for appinstalled and reports WebSDK appInstall via useTracker (trace_id from traceId, defaults to empty string). Only requires PWA to be enabled — not affected by the guide-display gates (installs from the browser menu count too); zero behavior when omitted

Return Values

NameTypeDescription
openRef<boolean>Whether the guide is shown. Auto-set to true after delay; set to false by dismiss()
platformRef<'ios' | 'android' | null>Target platform for the current device. null means no show (outer v-if="open" should gate this)
dismiss() => voidManually close. Only flips open; the "shown" memory was already persisted at trigger time

Storage Keys

ModeStorageKeyData
rememberFor: 'session'sessionStorage<cachePrefix>sw:a2hs:shownboolean (AES-encrypted)
rememberFor: N (positive)localStorage<cachePrefix>sw:a2hs:dismissedAtnumber timestamp (AES-encrypted)

The two modes use different keys, so switching rememberFor doesn't conflict. <cachePrefix> comes from runtimeConfig.public.cachePrefix for automatic isolation across projects sharing a domain.

Notes

  • This composable is intended for internal use by <SwAddToHomescreenGuide>. Custom UIs may consume it, but the framework does not guarantee return-value stability across patch versions.
  • The "shown" state is persisted at setTimeout fire (when open becomes true), not on user dismiss. This avoids the "user instantly closes but no record → reshows next visit" pitfall.
  • When PWA is disabled (pwa.enabled === false), dev mode prints a console warn advising to either enable PWA or remove the mount from app.vue.