Realtime & WebSockets

Build realtime experiences with NuxtHub using Cloudflare Workers & Durable Objects.

Getting Started

Enable Niro's experimental WebSocket support by adding the following to your nuxt.config.ts file:

nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    experimental: {
      websocket: true
    }
  },
  hub: {
    workers: true
  }
})
We need to enable the workers option to use the WebSocket support as Durable Objects are only supported on Cloudflare Workers.

Example

Let's create a simple application that display how many users are connected to the website.

First, let's create a websocket handler on /ws/visitors route:

server/routes/ws/visitors.ts
export default defineWebSocketHandler({
  open(peer) {
    // We subscribe to the 'visitors' channel
    peer.subscribe('visitors')
    // We publish the number of connected users to the 'visitors' channel
    peer.publish('visitors', peer.peers.size)
    // We send the number of connected users to the client
    peer.send(peer.peers.size)
  },
  close(peer) {
    peer.unsubscribe('visitors')
    // Wait 500ms before sending the updated locations to the server
    setTimeout(() => {
      peer.publish('visitors', peer.peers.size)
    }, 500)
  },
})

Install VueUse if you haven't already:

Terminal
npx nuxi module add vueuse

Let's use the useWebSocket composable from VueUse to subscribe to the visitors channel and display the number of connected users.

pages/visitors.vue
<script setup lang="ts">
const visitors = ref(0)
const { open } = useWebSocket('/ws/visitors', {
  immediate: false,
  async onMessage(ws, event) {
    // We parse the number of connected users from the message
    // The message might be a string or a Blob
    visitors.value = parseInt(typeof event.data === 'string' ? event.data : await event.data.text())
  },
})

// We open the connection when the component is mounted
onMounted(() => {
  open()
})
</script>

<template>
  <div>
    <h1>Visitors: {{ visitors }}</h1>
  </div>
</template>

See a full open source example on GitHub, including geolocation tracking.