nuxt: 'Window is not defined' where do I put client-side only scripts?
I’m trying to run a-frame in one of my vue pages but I’m getting an error in my browser:
ReferenceError: window is not defined
I’m guessing this is because nuxt is trying to run the aframe module while rendering the page on the server.
<template>
<div>
<a-scene fog="type: linear; color: #FFEBDE; far:190" debug>
<a-entity>
<a-collada-model src="/obj/banner.dae"></a-collada-model>
<a-ring color="teal" radius-inner="1" radius-outer="2"></a-ring>
</a-entity>
<a-entity position="0 -1 10">
<a-camera>
<a-cursor color="#2E3A87"></a-cursor>
</a-camera>
</a-entity>
<a-entity camera="userHeight: 1.6" look-controls></a-entity>
</a-scene>
</div>
</template>
<script>
import 'aframe';
export default {
mounted() {
}
}
</script>
<div align="right">This question is available on Nuxt.js community (#c30)</div>About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 29 (6 by maintainers)
Commits related to this issue
- feat: add Alpine Resolves #30 — committed to obsfeil/nuxt by Atinux a year ago
Hi, Yes, this is exactly due to the server-side rendering. If you need to specify that you want to import a ressource only on the client-side inside, you need to you
process.browser
variable..vue file
nuxt.config.js
Thanks for your report, the documentation of the website will be completed soon.
Vue-FullCalendar app/plugins/vue-fullcalendar.js
I know this issue is closed and all, but I just want to point out an alternate solution - Vue’s lifecycle hooks. All hooks except for
beforeCreate
andcreated
do not even run on the server. If you’re doing any client-side manipulation or inspection and referencing built-in browser globals likewindow
ordocument
, then you should do those things in these hooks. This solution removes the need to inspect environment variables.Documentation
Currently, nuxt.js
1.0.0-rc11
, it isprocess.browser
and notprocess.BROWSER_BUILD
inside a component.@andrewharvey could you provide more details or an example of this implementation using the
import
statement?I have experinced similar issues as well. I was trying to import a vue UI framework
element-ui
. However, it references window object and several native browser functions likeaddEventListener
etc., so it breaks the server rendering. I’m thinking if there is any way to polyfill it somehow. Because for such kind of UI framework, if we cannot render it on server side, it doesn’t quite make sense and is probably not usable for SEO purpose.I’ve also treid
next.js
withantd
( a UI framework built onReact.js
which similar toelement-ui
) and it worked almost perfectly ( except thatnext.js
is usingglamor
as acss-in-js
solution which is pretty hacky). When I have time I’ll dig more for the reason why it’s working innext.js
but notnuxt.js
.The only way I found to make scripts load only on the client side is to require them in one of the hooks that are not executed on the server side.
So for example with
mapbox-gl
you first set a parametermapboxgl
into thedata ()
object. Then inside your hook (for examplemounted ()
) you requiremapbox-gl
and assign it to the new parameter.You have to use
require
at the moment @andrewharvey and ask for the library author to add SSR support (by giving him this link if it’s a Vue.js library: https://ssr.vuejs.org/en/universal.html)How would that work if we are using import instead of require? If I put my import inside the if statement I get:
NuxtServerError Module build failed: SyntaxError: 'import' and 'export' may only appear at the top level
This is the best answer I’ve ever seen. Thanks
why is this still not in the docs? I followed what was there and was still having issues importing a vue plugin. this solution cleared things up
the plugin in question: https://github.com/Wanderxx/vue-fullcalendar
@Atinux I mean I’m pretty sure that
antd
has somewindow
object references as well. But when I tried it, it did work withnext.js
. However it probably because thatantd
is more modular and I missed the browser specific part of the variable references. Anyway I’m going to test more.Update: I’ve found that in
antd
it’s usingif (typeof window !== 'undefined')
to check if it’s in the browser. So as you said, it’s the plugin’s issue and it shouldn’t directly referencewindow
object without envirument detection.element-ui
IMO is a bit buggy.I think that every vue plugin should be able to work both client-side and server-side since the version 2.0 of Vue.js.
I asked the team behind
element-ui
but they said it’s not their priority, but I don’t think it will be complicated to make it compatible with server-side rendering, since we will only have to addif
statement where a client-side only function is called.@andyhu what library are you talking about which is working with next.js but not nuxt.js?