Search code examples
vue.jsnuxt.jsaddeventlistenernuxt3.jsvueuse

VueUse useEventListener - document not defined in Nuxt3


I though that useEventListener() from VueUse was supposed to automatically put the event listener registration into the onMounted hook, however, when I tried to use it in the following way, I got a Nuxt3 error - document is not defined:

<script lang="ts" setup>
useEventListener(document, 'keydown', (e: KeyboardEvent) => {
    if (e.key === 'Escape') {
        // ...
    }
})
</script>

Even on their website, they don't put the composable into a lifecycle hook: https://vueuse.org/core/useEventListener/

Did I misunderstand something? When I wrap it with if (process.client) { it obviously works, however, that defeats the purpose of having a composable that is supposed to make it easier to work with event listeners in my opinion.


Solution

  • It does work as intended. Should be a problem with your Nuxt setup.

    SFC Playground

    const { createApp } = Vue
    const { useEventListener } = VueUse
    
    const App = { 
      setup() {   
        console.log(`${new Date().toLocaleTimeString()} Start`)
        const cleanup = useEventListener(document, 'keydown', (e) => {
          if (e.key === 'Escape') {
             alert(`${new Date().toLocaleTimeString()} Esc`)
          }
       })
       return { cleanup }
      }
    }
    
    const app = createApp(App)
    const vm = app.mount('#app')
    #app { line-height: 2; }
    [v-cloak] { display: none; }
    <div id="app" v-cloak>
    <button @click="cleanup">cleanup</button>
    </div>
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
    <script src="https://unpkg.com/@vueuse/shared"></script>
    <script src="https://unpkg.com/@vueuse/core"></script>