A headless Vue component that gives you notification logic without imposing any UI.
<template>
<SkewNotification v-slot="{ isCurrentChunksOutdated, dismiss, reload, timeAgo }">
<div v-if="isCurrentChunksOutdated" class="notification">
<p>New version available! ({{ timeAgo }})</p>
<button @click="reload">
Reload
</button>
<button @click="dismiss">
Dismiss
</button>
</div>
</SkewNotification>
</template>
The component gives you these props via scoped slot:
versionstringThe user's current version (from cookie or buildId).
<SkewNotification v-slot="{ version }">
<div>
<p>Current version: {{ version }}</p>
</div>
</SkewNotification>
isCurrentChunksOutdatedbooleanWhether the notification should be shown.
Automatically set to true when:
open prop<SkewNotification v-slot="{ isCurrentChunksOutdated }">
<div v-if="isCurrentChunksOutdated">
Update available!
</div>
</SkewNotification>
dismiss()() => voidDismiss the notification (sets isCurrentChunksOutdated to false).
<SkewNotification v-slot="{ isCurrentChunksOutdated, dismiss }">
<div v-if="isCurrentChunksOutdated">
<p>Update available!</p>
<button @click="dismiss">Not now</button>
</div>
</SkewNotification>
reload()() => voidReload the page to get the new version.
Calls window.location.reload().
<SkewNotification v-slot="{ isCurrentChunksOutdated, reload }">
<div v-if="isCurrentChunksOutdated">
<button @click="reload">Update Now</button>
</div>
</SkewNotification>
timeAgostringHuman-readable time since the release.
Examples: "just now", "2 minutes ago", "1 hour ago"
<SkewNotification v-slot="{ isCurrentChunksOutdated, timeAgo }">
<div v-if="isCurrentChunksOutdated">
<p>Released {{ timeAgo }}</p>
</div>
</SkewNotification>
releaseDateDate | nullThe release date as a Date object.
<SkewNotification v-slot="{ isCurrentChunksOutdated, releaseDate }">
<div v-if="isCurrentChunksOutdated">
<p>Released: {{ releaseDate?.toLocaleString() }}</p>
</div>
</SkewNotification>
payloadChunksOutdatedPayload | nullPayload from chunks outdated event with detailed information.
<SkewNotification v-slot="{ isCurrentChunksOutdated, payload }">
<div v-if="isCurrentChunksOutdated">
<p>Deleted chunks: {{ payload?.deletedChunks.length }}</p>
<p>Invalidated modules: {{ payload?.invalidatedModules.length }}</p>
</div>
</SkewNotification>
isAppOutdatedbooleanWhether entire app is outdated (not just current chunks).
<SkewNotification v-slot="{ isAppOutdated }">
<div v-if="isAppOutdated">
<p>Full app update available</p>
</div>
</SkewNotification>
forceOpenbooleanundefinedForce notification open for testing/debugging.
<script setup>
const forceOpen = ref(true)
</script>
<template>
<SkewNotification v-slot="{ reload }" :force-open="forceOpen">
<div>
<button @click="reload">
Update
</button>
</div>
</SkewNotification>
</template>
@dismissEmitted when notification is dismissed.
<SkewNotification @dismiss="console.log('dismissed')">
<!-- ... -->
</SkewNotification>
@reloadEmitted when reload is triggered.
<SkewNotification @reload="console.log('reloading')">
<!-- ... -->
</SkewNotification>
See UI Examples for complete examples including Nuxt UI, toast notifications, banners, and more.