How to Fix Navigator/Window/Document Is Undefined in Nuxt

How to fix navigator / window / document is undefined in Nuxt

This is the solution to fix:

  • navigator is undefined
  • window is undefined
  • document is not defined

Here is an example on how you should wrap your logic JS code

<script>
import { jsPlumb } from 'jsplumb' // client-side library only, no SSR support

export default {
mounted() {
if (process.client) {
// your JS code here like >> jsPlumb.ready(function () {})
}
},
}
</script>

As shown here: https://nuxtjs.org/docs/2.x/internals-glossary/context

PS: mounted + process.client are kinda redundant because mounted only runs on the client.


Also, wrapping your component into <client-only> if you want it to be only client side rendered is also a good idea.

<template>
<div>
<p>this will be rendered on both: server + client</p>

<client-only>
<p>this one will only be rendered on client</p>
</client-only>
<div>
</template>

The documentation for this one is here: https://nuxtjs.org/docs/2.x/features/nuxt-components/#the-client-only-component

PS: beware because this client-only tag will only skip the rendering, not the execution, as explained here.


Some packages do not support SSR when you import them, for that you could either:

  • use a condition with a dynamic import (if the library is meant to be used later on)
  • directly like this (if you want to load a component like vue-editor)
export default {
components: {
[process.client && 'VueEditor']: () => import('vue2-editor'),
}
}

“window is not defined” in Nuxt.js

UPDATED AUGUST 2021

The Window is not defined error results from nodejs server side scripts not recognising the window object which is native to browsers only.

As of nuxt v2.4 you don't need to add the process.client or process.browser object.

Typically your nuxt plugin directory is structured as below:

~/plugins/myplugin.js

import Vue from 'vue';
// your imported custom plugin or in this scenario the 'vue-session' plugin
import VueSession from 'vue-session';

Vue.use(VueSession);

And then in your nuxt.config.js you can now add plugins to your project using the two methods below:

METHOD 1:

Add the mode property with the value 'client' to your plugin

plugins: [
{ src: '~/plugins/myplugin.js', mode: 'client' }
]


METHOD 2: (Simpler in my opinion)

Rename your plugin with the extension .client.js and then add it to your plugins in the nuxt.config.js plugins. Nuxt 2.4.x will recognize the plugin extension as to be rendered on the server side .server.js or the client side .client.js depending on the extension used.

NOTE: Adding the file without either the .client.js or .server.js extensions will render the plugin on both the client side and the server side. Read more here.

plugins: ['~/plugins/myplugin.client.js']

navigator.mediaDevices.getUserMedia - UNDEFINED in Nuxt

Thanks to @kissun for pointing me in the right direction.

I reckon this is a recurring issue because one cannot use navigator.mediaDevices.getUserMedia in dev mode.

I added this function in mounted as suggested, however that did not work either.

After searching online, I discovered I had to use HTTPS in dev mode for it to ultimately work.

To do that, create your HTTPS certificate and key first, and then configure nuxt. Original, full, instructions can be found here How to run NUXT (npm run dev) with HTTPS in localhost?

Sample Image

To setup nuxt, add this into your server object, in your nuxt.config.js file:

import path from 'path'
import fs from 'fs'

server: {
https: {
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
}
}

Now try using navigator.mediaDevices.getUserMedia

document is not defined in Nuxt.js

It's a common error when you start a Nuxt project ;-)

The Choices.js lib is available only for client-side! So Nuxt tried to renderer from server-side, but from Node.js window.document doesn't exist, then you have an error.

nb: window.document is only available from the browser renderer.

Since Nuxt 1.0.0 RC7, you can use <no-ssr> element to allow your component only for client-side.

<template>
<div>
<no-ssr placeholder="loading...">
<your-component>
</no-ssr>
</div>
</template>

take a look at the official example here: https://github.com/nuxt/nuxt.js/blob/dev/examples/no-ssr/pages/index.vue


Update:

Since Nuxt >= 2.9.0, you have to use the <client-only> element instead of <no-ssr>:

<template>
<div>
<client-only placeholder="loading...">
<your-component>
</client-only>
</div>
</template>

To know more, see nuxt docs: https://nuxtjs.org/docs/2.x/features/nuxt-components#the-client-only-component

Nuxtjs document is not defined

A wrote a similar answer here but it was lacking some parts, so I feel like I can answer here too.

Your library is probably in the same state as vue2-editor, meaning that you need to load & import it only on the client. For that, you could use something like this

export default {
components: {
[process.browser && 'star-rating']: () => import('vue-star-rating'),
}
}

Nuxt.js: window is not defined apexcharts/vue-apexcharts

As explained in my linked answer (last sentence, with the direct component syntax), here is how you make a proper working setup:

<template>
<div id="chart">
<client-only>
<apexchart
type="donut"
width="380"
:options="chartOptions"
:series="series"
></apexchart>
</client-only>
</div>
</template>

<script>
export default {
name: 'Donut',
components: {
[process.browser && 'apexchart']: () => import('vue-apexcharts'),
},
data() {
return {
series: [44, 55, 41, 17, 15],
chartOptions: {
chart: {
type: 'donut',
},
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200,
},
legend: {
position: 'bottom',
},
},
},
],
},
}
},
}
</script>

I've also removed a data who was nesting the whole configuration, already inside of data(). This was causing a non-match in terms of props as shown in the browser console errors.

jsPlumb integration with Nuxtjs throwing the error document is not defined

Instead of using process.client I used the process.browser and it worked fine for me. Please refer the link: https://stackoverflow.com/a/69822954/7584240

VueEditor document is not defined Nuxt.js

You can try to load it dynamically:

<template>
<div>
<SideBar />
<div class='content'>
<h1>Write article</h1>
<client-only>
<VueEditor
v-model='articleContent'
/>
</client-only>
<div style='margin-top: 15px'><button @click='postArticle'>Post article</button></div>
</div>
</div>
</template>

<script>
import SideBar from '../components/SideBar';
export default {
name: 'Articles',
components: {
SideBar,
VueEditor: () => process.client ? (await import("vue2-editor")).VueEditor : ""
},
data() {
return {
articleContent: null,
}
},
methods: {
postArticle() {
console.log(this.articleContent)
},
},
}
</script>


Related Topics



Leave a reply



Submit