Composables

useSkeletonizer and the skeleton-aware data composables.

Composables

useSkeletonizer()

const skeletonizer = useSkeletonizer()

skeletonizer.enable()          // turn skeleton mode on globally
skeletonizer.disable()         // turn it off
skeletonizer.toggle()          // flip it; returns the new boolean
skeletonizer.isEnabled         // ComputedRef<boolean>
skeletonizer.config            // reactive resolved config
skeletonizer.stats             // reactive runtime statistics
skeletonizer.refresh()         // re-scan all mounted hosts
skeletonizer.scan()            // re-scan; returns { nodes, svg, cacheHit }

skeletonizer.setTheme({ baseColor: '#ddd', highlightColor: '#fff' })
skeletonizer.setAnimation('pulse')
skeletonizer.registerAnimation({ name: 'blink', css: '' })

skeletonizer.config.renderMode  // always 'svg' (read-only)
skeletonizer.engine             // the per-app SkeletonEngine

scan() runs the pipeline (measure → render the SVG overlay) and returns a summary of the result:

const { nodes, svg, cacheHit } = skeletonizer.scan()
// nodes    — ScannedNode[] measured for this host (DOMRects, host-relative)
// svg      — the generated <svg> overlay element (or its markup)
// cacheHit — true when the SVG blueprint was served from the layout cache

It works at any scope — globally, per page, per component or per container — because all control flows through a single reactive store that every <Skeletonizer> host subscribes to.

stats

const { stats } = useSkeletonizer()
// { hosts, bones, ignored, scans, lastScanMs, enabled,
//   renderMode, score, fps, animationTier, memoryMB,
//   cacheHits, cacheMisses, degraded, timings }
// timings = { scanMs, renderMs, totalMs }

Reactive runtime statistics, also surfaced in the DevTools tab. renderMode is always 'svg'. The Step-3 fields (score, fps, animationTier, cache counters…) are populated by the adaptive engine when it is active.

useSkeletonPerformance()

The advanced performance / DevTools surface — telemetry, Explain Mode and the bottleneck ranking, plus the runtime controls. Backs a diagnostics dashboard (and the Performance Lab).

const perf = useSkeletonPerformance()

perf.stats                       // same reactive stats object
perf.telemetry()                 // { avgTotalMs, avgScanMs, cacheHitRatio, … }
perf.series('fps')               // number[] for a sparkline
perf.explanations()              // natural-language engine decisions (Explain Mode)
perf.lastExplanation             // ComputedRef<SkeletonExplainEntry | null>
perf.bottlenecks()               // hosts ranked by skeletonization cost
perf.cacheHitRatio               // ComputedRef<number> in [0,1]
perf.blueprint()                 // SvgBlueprint | null — the SVG Blueprint Inspector
perf.engine                      // the per-app SkeletonEngine

blueprint()

Returns the current SVG Blueprint for the active host (or null when nothing is skeletonized) — the serializable description of the generated overlay: the viewBox locked to the host bounding box, the shared gradient id (sk-shimmer-{uid}) and the list of shapes (<rect> / <circle>) with their host-relative coordinates. It powers the SVG Blueprint Inspector in DevTools, so you can read the exact vector the engine produced and confirm cache hits.

const bp = perf.blueprint()
// { uid, viewBox, gradientId, shapes: [{ kind: 'rect' | 'circle', x, y, … }], cached }

Skeleton-aware data composables

These mirror Nuxt's data composables and, when skeleton: true (the default), turn the global skeleton on while the request is pending and off when it settles — ref-counted, so concurrent requests compose correctly.

const { data } = await useSkeletonFetch('/api/users', { skeleton: true })

Available wrappers:

  • useSkeletonFetch — wraps useFetch
  • useSkeletonLazyFetch — wraps useLazyFetch
  • useSkeletonAsyncData — wraps useAsyncData
  • useSkeletonLazyAsyncData — wraps useLazyAsyncData

Pass { skeleton: false } to opt a single call out. Any <Skeletonizer> without an explicit :enabled follows this global state.

Prefer explicit control? Bind :enabled to a pending ref instead — see Nuxt Integration.