Core Concepts

View Active Connections

Last updated by Harlan Wilton in doc: internal links.

Track how many users are connected to your application and which versions they're running. This is useful for admin dashboards, deployment monitoring, and understanding rollout progress.

Connection tracking only works with sse or ws update strategies. It does not support polling or external adapters (Pusher/Ably).

Setup

Enable connection tracking in your Nuxt config using connectionTracking:

nuxt.config.ts
export default defineNuxtConfig({
  skewProtection: {
    connectionTracking: true
  }
})

Limitations

  • Single instance only: Stats are per-server process. With horizontal scaling, each instance only sees its own connections.
  • SSE/WS only: Does not work with polling strategy or external adapters (Pusher/Ably).
  • Bot traffic excluded: When @nuxtjs/robots is installed, bot/crawler traffic is automatically excluded from connection counts. See Bot Traffic Filtering.

Using the Composable

The useActiveConnections() composable provides reactive access to connection statistics:

<script setup lang="ts">
import { useActiveConnections } from '#imports'

const { total, versions } = useActiveConnections()
</script>

<template>
  <div>
    <p>Active users: {{ total }}</p>
    <ul>
      <li v-for="(count, version) in versions" :key="version">
        {{ version.slice(0, 8) }}: {{ count }} users
      </li>
    </ul>
  </div>
</template>

Return Values

PropertyTypeDescription
totalComputedRef<number>Total active connections
versionsComputedRef<Record<string, number>>Map of buildId → connection count

Example: Admin Dashboard

<script setup>
const { total, versions } = useActiveConnections()
const currentBuildId = useRuntimeConfig().app.buildId

const stats = computed(() => {
  const current = versions.value[currentBuildId] || 0
  const outdated = total.value - current
  return {
    total: total.value,
    current,
    outdated,
    percentUpToDate: total.value ? Math.round((current / total.value) * 100) : 100
  }
})
</script>

<template>
  <div class="grid grid-cols-4 gap-4">
    <div class="stat">
      <span class="label">Total Users</span>
      <span class="value">{{ stats.total }}</span>
    </div>
    <div class="stat">
      <span class="label">On Latest</span>
      <span class="value text-green">{{ stats.current }}</span>
    </div>
    <div class="stat">
      <span class="label">On Old Version</span>
      <span class="value text-orange">{{ stats.outdated }}</span>
    </div>
    <div class="stat">
      <span class="label">Rollout Progress</span>
      <span class="value">{{ stats.percentUpToDate }}%</span>
    </div>
  </div>
</template>

Custom Behavior with Hooks

For advanced use cases, you can use hooks directly instead of the composable.

Client-Side: skew:message

Listen to all messages from the SSE/WebSocket connection:

plugins/custom-stats.client.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hooks.hook('skew:message', (message) => {
    if (message.type === 'stats') {
      // Custom handling
      console.log('Connections:', message.total)
      console.log('Versions:', message.versions)
    }
  })
})

Server-Side: Connection Lifecycle

Build custom tracking logic with Nitro hooks:

server/plugins/custom-tracking.ts
import { defineNitroPlugin } from 'nitropack/runtime'

export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('skew:connection:open', ({ id, version, send }) => {
    console.log(`Client ${id} connected on ${version}`)

    // Send custom welcome message
    send({ type: 'welcome', serverTime: Date.now() })
  })

  nitroApp.hooks.hook('skew:connection:close', ({ id }) => {
    console.log(`Client ${id} disconnected`)
  })
})

See Nuxt Hooks and Nitro Hooks for full documentation.

Did this page help you?