useSkewProtection()
Use useSkewProtection() to read version state, manage connections, and handle updates.
Usage
const skew = useSkewProtection()Options
The lazy option (boolean, default false) controls whether the composable establishes the connection automatically when called in a mounted component. When true, you must call connect() manually.
// Auto-connect on mount (default)
const skew = useSkewProtection()
// Manual connection control
const skew = useSkewProtection({ lazy: true })
skew.connect() // Connect when readyReturns
manifest
- Type:
Ref<NuxtAppManifestMeta | null>
The current build manifest from builds/latest.json.
const { manifest } = useSkewProtection()
console.log(manifest.value?.id) // Current buildId
console.log(manifest.value?.timestamp) // Build timestampclientVersion
- Type:
string
The user's current version (from cookie or buildId).
const { clientVersion } = useSkewProtection()
console.log(clientVersion) // "abc123"isAppOutdated
- Type:
ComputedRef<boolean>
Whether the user's version is outdated.
const { isAppOutdated } = useSkewProtection()
if (isAppOutdated.value) {
console.log('User is on an old version')
}isConnected
- Type:
ComputedRef<boolean>
Whether this tab subscribes to push updates. With shared ownership, a waiting tab also reports connected. The owner opens the SSE/WebSocket connection. Polling uses no push connection.
const { isConnected } = useSkewProtection()
if (isConnected.value) {
console.log('Connected to update stream')
}connect()
- Type:
() => void
Manually establish the connection. Only needed when using lazy: true.
const skew = useSkewProtection({ lazy: true })
// Connect when user clicks a button
function handleConnect() {
skew.connect()
}disconnect()
- Type:
() => void
Manually close the connection. Useful for cleanup or pausing updates.
const { disconnect } = useSkewProtection()
// Disconnect when leaving a section
onBeforeRouteLeave(() => {
disconnect()
})checkForUpdates()
- Type:
() => Promise<void>
Manually trigger an update check.
const { checkForUpdates } = useSkewProtection()
// Check for updates
await checkForUpdates()onAppOutdated()
- Type:
(callback: (manifest: NuxtAppManifestMeta | null) => void) => void
Triggers when it detects a new version, regardless of whether it affects the current session. Uses Nuxt's built-in app:manifest:update hook.
If an update was already detected, registration immediately calls your callback with the retained manifest.
Use case: Make next page load a hard navigation (forces HTML reload).
const { onAppOutdated } = useSkewProtection()
onAppOutdated((manifest) => {
console.log('New version available:', manifest?.id)
// Show passive "Update available" badge
})onCurrentChunksOutdated()
- Type:
(callback: (payload: ChunksOutdatedPayload) => void) => void
Triggers only when the user's loaded JavaScript modules have been changed in a new deployment.
For example, a user is reading a blog post when you deploy a homepage change. If their loaded chunks stay unchanged, the callback does not run.
A service worker tracks the loaded modules.
If chunk invalidation was already detected, registration immediately calls your callback with the retained payload.
const { onCurrentChunksOutdated } = useSkewProtection()
onCurrentChunksOutdated((payload) => {
console.log('Deleted chunks:', payload.deletedChunks)
console.log('Invalidated modules:', payload.invalidatedModules)
console.log('Passed releases:', payload.passedReleases)
// Show notification
alert('Please reload to get the latest version')
})Type Definitions
interface NuxtAppManifestMeta {
id: string
timestamp: number
skewProtection?: {
current: string
versions: Record<string, VersionInfo>
}
}
interface VersionInfo {
timestamp: string
}
interface ChunksOutdatedPayload {
deletedChunks: string[]
invalidatedModules: string[]
passedReleases: string[]
}Examples
Custom Invalidation Handler
const { onCurrentChunksOutdated } = useSkewProtection()
onCurrentChunksOutdated(({ invalidatedModules, passedReleases }) => {
// Track in analytics
analytics.track('chunks_outdated', {
count: invalidatedModules.length,
modules: invalidatedModules,
releases: passedReleases
})
// Show custom UI
showUpdateDialog({
title: 'Update Required',
message: `${invalidatedModules.length} modules need updating (${passedReleases.length} releases passed)`
})
})Version Information Display
<script setup lang="ts">
const { clientVersion, manifest } = useSkewProtection()
const buildDate = computed(() => {
if (!manifest.value?.timestamp)
return null
return new Date(manifest.value.timestamp).toLocaleString()
})
</script>
<template>
<div class="version-info">
<p>Your version: {{ clientVersion }}</p>
<p>Latest version: {{ manifest?.id }}</p>
<p>Build date: {{ buildDate }}</p>
</div>
</template>Programmatic Update Check
Note: Only relevant if you're using polling.
const { checkForUpdates, isAppOutdated } = useSkewProtection()
async function handleUserAction() {
// Check for updates before critical action
await checkForUpdates()
if (isAppOutdated.value) {
const shouldReload = confirm('A new version is available. Reload now?')
if (shouldReload) {
window.location.reload()
}
}
else {
// Proceed with action
await performCriticalAction()
}
}