I am trying to convert my code from Nuxt 2 to Nuxt 3, and I have run into an issue with creating a websocket server in Nuxt 3.
It works perfectly fine in Nuxt 2 using this code:
// Nuxt 2: modules/socket.js
import http from 'http'
import socketIO from 'socket.io'
export default function () {
this.nuxt.hook('render:before', () => {
const server = http.createServer(this.nuxt.renderer.app)
const io = socketIO(server)
this.nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
this.nuxt.hook('close', () => new Promise(server.close))
io.on('connection', (socket) => {
console.log("CONNECTED")
})
})
}
// Nuxt 2: plugins/socket.client.js
import io from 'socket.io-client'
const socket = io('http://localhost:3000')
export default ({}, inject) => {
inject('socket', socket)
}
<!-- Nuxt 2: pages/index.vue -->
<template>
<div>
<p>Check socket status in Vue devtools...</p>
</div>
</template>
<script>
export default {
computed: {
socket() {
return this.$socket ? this.$socket : {};
}
}
}
</script>
However, in Nuxt 3 I cannot access this.nuxt.renderer.app in the modules/socket.js file (for http.createServer(...)), and I cannot figure out how to access the correct renderer.app elsewhere in a Nuxt3 module. My Nuxt 3 code looks like this:
// Nuxt 3: modules/socket.js
import http from 'http'
import socketIO from 'socket.io'
export default (_, nuxt) => {
// Note that I use the 'ready' hook here - render:before is apparently not included in Nuxt3.
nuxt.hook('ready', renderer => {
// nuxt.renderer is undefined, so I've tried with renderer.app instead, with no luck.
const server = http.createServer(renderer.app)
const io = socketIO(server)
nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
nuxt.hook('close', () => new Promise(server.close))
io.on('connection', () => {
console.log("CONNECTION")
})
})
}
// Nuxt 3: plugins/socket.client.js
import io from 'socket.io-client'
export default defineNuxtPlugin(() => {
const socket = io('http://localhost:3000')
return {
provide: {
socket: socket
}
}
})
<!-- Nuxt 3: app.vue -->
<template>
<div>
<p>Check socket status in Vue devtools...</p>
</div>
</template>
<script setup>
const { $socket } = useNuxtApp()
</script>
I would make a codesandbox link for you, but every time I try, it breaks before I even add any code. I think it does not correctly work with Nuxt3 yet. Has anyone successfully established a websocket server in a Nuxt 3 module yet? Or can anyone see what I am missing?
I am interested in any working solution, it does not necessarily have to be socket.io.