Window is not defined ошибка

Next.js is a React framework with pre-rendering abilities. This means that for every page, Next.js will try to generate the HTML of the page for better SEO and performance.

This is why, if you’re trying to do this:

// components/Scroll.js
window.addEventListener("scroll", function() {
  console.log("scroll!")
});

Enter fullscreen mode

Exit fullscreen mode

Then it will fail with «ReferenceError: window is not defined»:

React error

Because in the Node.js world, window is not defined, window is only available in browsers.

There are three ways to solve that:

1. First solution: typeof

While you can’t use:

if (window !== undefined) {
  // browser code
}

Enter fullscreen mode

Exit fullscreen mode

Because this would try to compare a non-existent variable (window) to undefined, resulting in the mighty «ReferenceError: window is not defined». You can still use:

if (typeof window !== "undefined") {
  // browser code
}

Enter fullscreen mode

Exit fullscreen mode

Because typeof won’t try to evaluate «window», it will only try to get its type, in our case in Node.js: «undefined».

PS: Thanks to
Rogier Nitschelm for reminding me about this. I initially tried to do if (typeof window !== undefined) and this failed hard because of the reasons mentioned earlier.

The other solutions below are more exotic but still worth it.

2. Second solution: the useEffect hook

The «React» way to solve this issue would be to use the useEffect React hook. Which only runs at the rendering phase, so it won’t run on the server.

Let’s update our scroll.js component:

// components/Scroll.js

import React, { useEffect } from "react";

export default function Scroll() {
  useEffect(function mount() {
    function onScroll() {
      console.log("scroll!");
    }

    window.addEventListener("scroll", onScroll);

    return function unMount() {
      window.removeEventListener("scroll", onScroll);
    };
  });

  return null;
}

Enter fullscreen mode

Exit fullscreen mode

What we’ve done here is to turn our initial JavaScript file into a true React component that then needs to be added to your React tree via:

// pages/index.js

import Scroll from "../components/Scroll";

export default function Home() {
  return (
    <div style={{ minHeight: "1000px" }}>
      <h1>Home</h1>
      <Scroll />
    </div>
  );
}

Enter fullscreen mode

Exit fullscreen mode

Tip: The way we use useEffect in the example is to register and unregister the listeners on mount/unmount. But you could also just register on mount and ignore any other rendering event, to do so you would do this:

// components/Scroll.js

import React, { useEffect } from "react";

export default function Scroll() {
  useEffect(function onFirstMount() {
    function onScroll() {
      console.log("scroll!");
    }

    window.addEventListener("scroll", onScroll);
  }, []); // empty dependencies array means "run this once on first mount"

  return null;
}

Enter fullscreen mode

Exit fullscreen mode

3. Third solution: dynamic loading

A different solution is to load your Scroll component using dynamic imports and the srr: false option. This way your component won’t even be rendered on the server-side at all.

This solution works particularly well when you’re importing external modules depending on window. (Thanks Justin!)

// components/Scroll.js

function onScroll() {
  console.log("scroll!");
}

window.addEventListener("scroll", onScroll);

export default function Scroll() {
  return null;
}

Enter fullscreen mode

Exit fullscreen mode

// pages/index.js

import dynamic from "next/dynamic";

const Scroll = dynamic(
  () => {
    return import("../components/Scroll");
  },
  { ssr: false }
);

export default function Home() {
  return (
    <div style={{ minHeight: "1000px" }}>
      <h1>Home</h1>
      <Scroll />
    </div>
  );
}

Enter fullscreen mode

Exit fullscreen mode

If you do not need the features of useEffect, you can even remove its usage completely as shown here.

Finally, you could also load your Scroll component only in _app.js if what you’re trying to achieve is to globally load a component and forget about it (no more mount/unmount on page change).

I have used this technique to display a top level progress bar with NProgress in this article:

In my Next.js app I can’t seem to access window:

Unhandled Rejection (ReferenceError): window is not defined

componentWillMount() {
    console.log('window.innerHeight', window.innerHeight);
}

Enter image description here

Peter Mortensen's user avatar

asked Mar 13, 2019 at 20:53

Leon Gaban's user avatar

Leon GabanLeon Gaban

35.9k112 gold badges328 silver badges524 bronze badges

1

̶A̶n̶o̶t̶h̶e̶r̶ ̶s̶o̶l̶u̶t̶i̶o̶n̶ ̶i̶s̶ ̶b̶y̶ ̶u̶s̶i̶n̶g̶ ̶p̶r̶o̶c̶e̶s̶s̶.̶b̶r̶o̶w̶s̶e̶r ̶ ̶t̶o̶ ̶j̶u̶s̶t̶ ̶e̶x̶e̶c̶u̶t̶e̶ ̶ ̶y̶o̶u̶r̶ ̶c̶o̶m̶m̶a̶n̶d̶ ̶d̶u̶r̶i̶n̶g̶ ̶r̶e̶n̶d̶e̶r̶i̶n̶g̶ ̶o̶n̶ ̶t̶h̶e̶ ̶c̶l̶i̶e̶n̶t̶ ̶s̶i̶d̶e̶ ̶o̶n̶l̶y̶.

But process object has been deprecated in Webpack5 and also NextJS, because it is a NodeJS variable for backend side only.

So we have to use back window object from the browser.

if (typeof window !== "undefined") {
  // Client-side-only code
}

Other solution is by using react hook to replace componentDidMount:

useEffect(() => {
    // Client-side-only code
})

answered Mar 16, 2019 at 11:46

Darryl RN's user avatar

7

If you use React Hooks you can move the code into the Effect Hook:

import * as React from "react";

export const MyComp = () => {

  React.useEffect(() => {
    // window is accessible here.
    console.log("window.innerHeight", window.innerHeight);
  }, []);

  return (<div></div>)
}

The code inside useEffect is only executed on the client (in the browser), thus it has access to window.

Dylan Pierce's user avatar

Dylan Pierce

4,2333 gold badges35 silver badges43 bronze badges

answered Dec 19, 2019 at 3:42

Rotareti's user avatar

RotaretiRotareti

48.5k21 gold badges111 silver badges106 bronze badges

2

Move the code from componentWillMount() to componentDidMount():

componentDidMount() {
  console.log('window.innerHeight', window.innerHeight);
}

In Next.js, componentDidMount() is executed only on the client where window and other browser specific APIs will be available. From the Next.js wiki:

Next.js is universal, which means it executes code first server-side,
then client-side. The window object is only present client-side, so if
you absolutely need to have access to it in some React component, you
should put that code in componentDidMount. This lifecycle method will
only be executed on the client. You may also want to check if there
isn’t some alternative universal library which may suit your needs.

Along the same lines, componentWillMount() will be deprecated in v17 of React, so it effectively will be potentially unsafe to use in the very near future.

Alan W. Smith's user avatar

answered Mar 13, 2019 at 21:01

Alexander Staroselsky's user avatar

0

With No SSR

https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(
  () => import('../components/hello3'),
  { ssr: false }
)

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home

tanguy_k's user avatar

tanguy_k

11.1k6 gold badges53 silver badges57 bronze badges

answered Sep 9, 2019 at 5:28

Kate's user avatar

KateKate

1,0878 silver badges7 bronze badges

5

The error occurs because window is not yet available, while component is still mounting. You can access window object after component is mounted.

You can create a very useful hook for getting dynamic window.innerHeight or window.innerWidth

const useDeviceSize = () => {

  const [width, setWidth] = useState(0)
  const [height, setHeight] = useState(0)

  const handleWindowResize = () => {
    setWidth(window.innerWidth);
    setHeight(window.innerHeight);
  }

  useEffect(() => {
    // component is mounted and window is available
    handleWindowResize();
    window.addEventListener('resize', handleWindowResize);
    // unsubscribe from the event on component unmount
    return () => window.removeEventListener('resize', handleWindowResize);
  }, []);

  return [width, height]

}

export default useDeviceSize 

Use case:

const [width, height] = useDeviceSize();

answered Jul 24, 2021 at 10:45

Ismoil Shokirov's user avatar

Ismoil ShokirovIsmoil Shokirov

2,0632 gold badges14 silver badges32 bronze badges

3

componentWillMount() lifecycle hook works both on server as well as client side. In your case server would not know about window or document during page serving, the suggestion is to move the code to either

Solution 1:

componentDidMount()

Or, Solution 2

In case it is something that you only want to perform in then you could write something like:

componentWillMount() {
    if (typeof window !== 'undefined') {
        console.log('window.innerHeight', window.innerHeight);
    }
}

3limin4t0r's user avatar

3limin4t0r

18.9k2 gold badges29 silver badges52 bronze badges

answered Mar 14, 2019 at 5:28

RAVINDER MAHAJAN's user avatar

In the constructor of your class Component you can add

if (typeof window === 'undefined') {
    global.window = {}
}

Example:

import React, { Component } from 'react'

class MyClassName extends Component {

    constructor(props){
        super(props)
        ...
        if (typeof window === 'undefined') {
            global.window = {}
        }
}

This will avoid the error (in my case, the error would occur after I would click reload of the page).

Peter Mortensen's user avatar

answered Nov 25, 2019 at 17:42

RealScatman's user avatar

RealScatmanRealScatman

3583 silver badges5 bronze badges

3

A bit late but you could also consider using Dynamic Imports from next turn off SSR for that component.

You can warp the import for your component inside a dynamic function and then, use the returned value as the actual component.

import dynamic from 'next/dynamic'

const BoardDynamic = dynamic(() => import('../components/Board.tsx'), {
  ssr: false,
})

<>
   <BoardDynamic />
</>

answered Feb 16, 2022 at 21:44

Parsa Safavi's user avatar

1

Best solution ever

import dynamic from 'next/dynamic';

const Chart = dynamic(()=> import('react-apexcharts'), {
    ssr:false,
})

answered Dec 2, 2021 at 15:43

Vinicius Pollo's user avatar

3

global?.window && window.innerHeight

It’s important to use the operator ?., otherwise the build command might crash.

answered May 2, 2022 at 15:36

lucgauer's user avatar

lucgauerlucgauer

1051 silver badge7 bronze badges

I have to access the hash from the URL so I come up with this

const hash = global.window && window.location.hash;

answered Mar 7, 2021 at 5:04

U.A's user avatar

U.AU.A

2,9613 gold badges24 silver badges36 bronze badges

2

Here’s an easy-to-use workaround that I did.

const runOnClient = (func: () => any) => {
  if (typeof window !== "undefined") {
    if (window.document.readyState == "loading") {
      window.addEventListener("load", func);
    } else {
      func();
    }
  }
};

Usage:

runOnClient(() => {
// access window as you like
})

// or async
runOnClient(async () => {
// remember to catch errors that might be raised in promises, and use the `await` keyword wherever needed
})

This is better than just typeof window !== "undefined", because if you just check that the window is not undefined, it won’t work if your page was redirected to, it just works once while loading. But this workaround works even if the page was redirected to, not just once while loading.

answered Oct 18, 2021 at 10:35

524F4A's user avatar

524F4A524F4A

7381 gold badge5 silver badges18 bronze badges

5

I was facing the same problem when i was developing a web application in next.js This fixed my problem, you have to refer to refer the window object in a life cycle method or a react Hook. For example lets say i want to create a store variable with redux and in this store i want to use a windows object i can do it as follows:

let store
useEffect(()=>{
    store = createStore(rootReducers,   window.__REDUX_DEVTOOLS_EXTENSION__ && 
    window.__REDUX_DEVTOOLS_EXTENSION__())
 }, [])
 ....

So basically, when you are working with window’s object always use a hook to play around or componentDidMount() life cycle method

answered Oct 14, 2020 at 18:03

crispengari's user avatar

crispengaricrispengari

7,5335 gold badges42 silver badges53 bronze badges

I wrapped the general solution (if (typeof window === 'undefined') return;) in a custom hook, that I am very pleased with. It has a similiar interface to reacts useMemo hook which I really like.

import { useEffect, useMemo, useState } from "react";

const InitialState = Symbol("initial");

/**
 *
 * @param clientFactory Factory function similiar to `useMemo`. However, this function is only ever called on the client and will transform any returned promises into their resolved values.
 * @param deps Factory function dependencies, just like in `useMemo`.
 * @param serverFactory Factory function that may be called server side. Unlike the `clientFactory` function a resulting `Promise` will not be resolved, and will continue to be returned while the `clientFactory` is pending.
 */
export function useClientSideMemo<T = any, K = T>(
  clientFactory: () => T | Promise<T>,
  deps: Parameters<typeof useMemo>["1"],
  serverFactory?: () => K
) {
  const [memoized, setMemoized] = useState<T | typeof InitialState>(
    InitialState
  );

  useEffect(() => {
    (async () => {
      setMemoized(await clientFactory());
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, deps);

  return typeof window === "undefined" || memoized === InitialState
    ? serverFactory?.()
    : memoized;
}

Usage Example:

I am using it to dynamically import libaries that are not compatible with SSR in next.js, since its own dynamic import is only compatible with components.

  const renderer = useClientSideMemo(
    async () =>
      (await import("@/components/table/renderers/HighlightTextRenderer"))
        .HighlightTextRendererAlias,
    [],
    () => "text"
  );

As you can see I even implemented a fallback factory callback, so you may provide a result when initially rendering on the server aswell. In all other aspects this hook should behave similiar to reacts useMemo hook. Open to feedback.

answered Jul 31, 2022 at 13:12

tlt's user avatar

tlttlt

3394 silver badges10 bronze badges

For such cases, Next.js has Dynamic Import.

A module that includes a library that only works in the browser, it’s suggested to use Dynamic Import. Refer

answered Jul 5, 2021 at 19:51

San-Mak's user avatar

San-MakSan-Mak

111 silver badge4 bronze badges

Date: 06/08/2021

Check if the window object exists or not and then follow the code along with it.

 function getSelectedAddress() {
    if (typeof window === 'undefined') return;

    // Some other logic
 }

answered Aug 6, 2021 at 15:15

Mohamed Jakkariya's user avatar

For Next.js version 12.1.0, I find that we can use process.title to determine whether we are in browser or in node side. Hope it helps!

export default function Projects(props) {
    console.log({ 'process?.title': process?.title });

    return (
        <div></div>
    );
}

1. From the terminal, I receive { 'process?.title': 'node' }

process.title === 'node'

2. From Chrome devtool, I revice { 'process?.title': 'browser' }

process.title === 'browser'

answered May 7, 2022 at 20:51

W.K.C's user avatar

W.K.CW.K.C

451 gold badge1 silver badge8 bronze badges

I had this same issue when refreshing the page (caused by an import that didn’t work well with SSR).

What fixed it for me was going to pages where this was occurring and forcing the import to be dynamic:

import dynamic from 'next/dynamic';


const SomeComponent = dynamic(()=>{return import('../Components/SomeComponent')}, {ssr: false});

//import SomeComponent from '../Components/SomeComponent'

Commenting out the original import and importing the component dynamically forces the client-side rendering of the component.

The dynamic import is covered in Nextjs’s documentation here:
https://nextjs.org/docs/advanced-features/dynamic-import

I got to this solution by watching the youtube video here:
https://www.youtube.com/watch?v=DA0ie1RPP6g

answered Jul 14, 2022 at 5:48

Nick Weimer's user avatar

Nick WeimerNick Weimer

4375 silver badges7 bronze badges

You can define a state var and use the window event handle to handle changes like so.

const [height, setHeight] = useState();

useEffect(() => {
    if (!height) setHeight(window.innerHeight - 140);
    window.addEventListener("resize", () => {
        setHeight(window.innerHeight - 140);
    });
}, []);

answered Sep 1, 2021 at 14:08

Seth Samuel's user avatar

You can try the below code snippet for use-cases such as — to get current pathname (CurrentUrl Path)

 import { useRouter } from "next/router";

 const navigator = useRouter()
 console.log(navigator.pathname);

answered Jul 19, 2022 at 15:22

Inder Pal Singh's user avatar

For anyone who somehow cannot use hook (for example, function component):

Use setTimeout(() => yourFunctionWithWindow()); will allow it get the window instance. Guess it just need a little more time to load.

answered Aug 27, 2022 at 12:49

Terry Windwalker's user avatar

Terry WindwalkerTerry Windwalker

1,2512 gold badges14 silver badges33 bronze badges

I want to leave this approach that I found interesting for future researchers. It’s using a custom hook useEventListener that can be used in so many others needs.

Note that you will need to apply a little change in the originally posted one, like I suggest here.

So it will finish like this:

import { useRef, useEffect } from 'react'

export const useEventListener = (eventName, handler, element) => {
  const savedHandler = useRef()

  useEffect(() => {
    savedHandler.current = handler
  }, [handler])

  useEffect(() => {
    element = !element ? window : element
    const isSupported = element && element.addEventListener
    if (!isSupported) return

    const eventListener = (event) => savedHandler.current(event)

    element.addEventListener(eventName, eventListener)

    return () => {
      element.removeEventListener(eventName, eventListener)
    }
  }, [eventName, element])
}

answered Nov 30, 2021 at 22:18

Lianel's user avatar

LianelLianel

1019 bronze badges

If it is NextJS app and inside _document.js, use below:

<script dangerouslySetInnerHTML={{
        __html: `
            var innerHeight = window.innerHeight;
        `
        }} />

answered Dec 16, 2021 at 10:49

Lakshit Nagar's user avatar

Table of Contents

Hide

  1. What is ReferenceError : window is not defined?
  2. How to fix ReferenceError : window is not defined?
    1. Solution 1: Check whether browser or server-side execution
    2. Solution 2: If error occurs while running on browser
    3. How to use Global variable in Node.js?
  3. Conclusion

The ReferenceError : window is not defined error mainly occurs if you are using the window object in Node.js, React.js, Next.js. The window object mainly exists in the browser context and not on the server context.

In this tutorial, we will look at what exactly is ReferenceError : window is not defined means and how to resolve this error with examples.

Let us look into some basics first.

ReferenceError: This class of error occurs when we try to reference a variable that does not exist in the current scope or is waiting for initialization.

Window: It denotes a window containing a DOM document and it is only available in browser context.

Now we will examine various reasons for the occurrence of this error.

1. In the case of using window in Node.js

As explained above, window contains a DOM document and is only available in the browser. Node.js does not support a browser environment. Node is a server-side runtime, ‘window‘ variable does not work for it.

2. In the case of using window in next.js/React.js

Next.js can render React on the client as well as on the server. It generally pre-renders the page using the node server. In this particular setup, we cannot access window. This causes the reference error.

3. Misspelled /Misplaced ‘window’ variable

Sometimes this error also occurs on the browser where it is configured to run correctly. Error on the browser end generally happens if we misplace the JavaScript script tag or misspell the window global variable.

How to fix ReferenceError : window is not defined?

The solution depends on where you are trying to access the window object. Let us take a look at each of the scenarios.

Solution 1: Check whether browser or server-side execution

In the case of React/Next.js applications, we can check the execution environment beforehand. If the window is defined (browser), the execution will continue. 

Let us look at the code snippet on how to check if window object exists.

if (typeof window !== 'undefined') {
  console.log('You are on the browser,You are good to go')
  } else {
  console.log('You are on the server,Cannot execute')
 }

We use the built-in typeOf operator to confirm that the window is defined. If it is defined, then the window execution takes place. We must remember that ‘undefinedshould always be in single quotes, or the comparison will fail.

if (typeof window !== undefined) {
  console.log('You are on the browser,You are good to go')
  } else {
  console.log('You are on the server,Cannot execute')
 } // It will always go in else block

Solution 2: If error occurs while running on browser

The window is not defined reference error may also occur in case of browser execution. It can happen due to misspelled keywords or a mispositioned script tag.

Let us discuss this with an example.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <!-- HTML Code here -->

    <!-- Script tag at bottom of body -->
    <script type="" src="test.js"></script>
  </body>
</html>

There might be some addons/Library inclusions that must be included before DOM creation. If we invoke the Script tag before the addons, it may give an error.

Secondly, a spelling error can also cause this malfunction. There is a big difference between ‘Window‘ and ‘window

Window: is a function, the constructor of the windows.

window: is the global variable representing the browser window containing your document.

Let us take a simple example to demonstrate the difference between Window and window

var countVal = 1; 
var showCount = () => console.log(countVal); 
console.log(window.countVal); 
window.showCount();

Output

1 
counter 1
var countVal = 1; 
var showCount = () => console.log(countVal); 
console.log(Window.countVal); 
Window.showCount(); 

// Output: Uncaught TypeError: Window.showCount is not a function

How to use Global variable in Node.js?

If you need to define global variables in Node.js, then we can define them using global, not window.

Let us take a simple example to see how it works

global.count = 5;

// Better way is to export the variable
export const count = 5;

Now we can import this in any of the files and use this constant.

import {count} from './main.js';


console.log(count); 

// Output: 5

Conclusion

We can conclude that we cannot use window on the server environment as they were developed to run on the browser, doing that will result in ReferenceError : window is not defined.

We can solve this issue on React.js and Next.js code using typeOf operator and we can check the reference variable exists. If the error occurs on the browser, check placement and syntax for window object.

Related Tags
  • ReferenceError,
  • window

Sign Up for Our Newsletters

Get notified on the latest articles

By checking this box, you confirm that you have read and are agreeing to our terms of use regarding the storage of the data submitted through this form.

Table of Contents

If you are working with Next.js and accessing the window object for the first time, there are high chances that you have seen the below error:

ReferenceError: window is not defined

In this article, we will see why this error occurs and different ways to fix the error.

Project setup

First, let’s create a Next.js application using the following command:

1npx create-next-app next-window-not-defined

Reproducing the error

Once the project is setup, update the index.js with the following code:

index.js

1import styles from "../styles/Home.module.css"

2

3export default function Home() {

4 window

.welcomeMessage = "Welcome to CodingDeft!"

5 return <div className={styles.container}>Hello</div>

6}

Here inside the Home component, we are setting a value to window.welcomeMessage.
In JavaScript applications or normal react applications, this should work fine.
But if we run the code and see we will see the following error:

window not defined error

Also, if you check the terminal where you have started the application, you will see the error there as well:

terminal window not defined error

The root cause of the error

As you can see the error occurs in the terminal itself.
That means it is a compilation error.

Next.js is compiled/built on Node.js runtime and Node.js does not have the the window object.

Now you may ask, why it should run on Node.js?
This is because, Next.js is server-side rendered,
and it runs the component code in the server, sends the HTML to the browser, and the HTML gets hydrated in the browser.

Different ways of fixing the error

In this section, we will explore different ways how to fix the error

Checking if the window is defined

The very obvious fix would be to check if the window object exists or not, and access the window only if it exists.

index.js

1import styles from "../styles/Home.module.css"

2

3export default function Home() {

4 if (typeof window !== "undefined") {

5 window.welcomeMessage = "Welcome to CodingDeft!"

6 }

7 return <div className={styles.container}>Hello</div>

8}

Now if you run the code, you will not see the error.

Accessing the window inside useEffect

The useEffect hook does not run in the server side.
So we can have the code which needs to run only on the client-side inside a useEffect hook.

index.js

1import styles from "../styles/Home.module.css"

2

3export default function Home() {

4 useEffect(() => {

5 window.welcomeMessage = "Welcome to CodingDeft!"

6 }, [])

7

8

return <div className={styles.container}>Hello</div>

9}

Dynamic imports in Next.js

Say you are accessing the window object in multiple places within your component,
and it would not be feasible to use the above methods all the time.

In cases where you want the whole component to be run only on the client side,
you can use the dynamic import
feature of Next.js

First, let’s create folder named components in the root of the project and a component named ClientComponent inside it:

ClientComponent.js

1import React from "react"

2

3const ClientComponent = () => {

4 window.welcomeMessage = "Welcome to CodingDeft!"

5

6 return <div>Hello</div>

7}

8

9export default ClientComponent

Now we can import the ClientComponent dynamically as shown below:

index.js

1import styles from "../styles/Home.module.css"

2

3import dynamic from "next/dynamic"

4

5const ClientComponent = dynamic(() => import("../components/ClientComponent"), {

6

7 ssr: false,

8})

9

10export default function Home() {

11 return (

12 <div className={styles.container}>

13 <ClientComponent />

14 </div>

15 )

16}

Now if you run the code, you will not see the error.

If you have liked article, do follow me on twitter to get more real time updates!

JavaScript is a programming language with the sole purpose of allowing developers to add interactivity to web pages. At least, that was its sole purpose. Until Node.js came out. That brought JavaScript out from under the hood of the client and into the world of servers and other non-browser based programming applications.

Since its original purpose was to provide functionality for client-side development, JavaScript was built with many useful features that are only useful when working within a browser. Now that JavaScript is used just about everywhere, some care needs to be taken to ensure that you are not trying to do something browser specific while not in a browser environment.

The Problem

It is not uncommon to want or need to access the window global object from your JavaScript code. For example, you may be trying to access a web page’s innerWidth or innerHeight from the window object. Whatever the case may be, in some situations you might find yourself confronted by a message in your console: ReferenceError: window is not defined

undefined_window_error

There could be a few different reasons why this is happening, but the cause is all the same: you are attempting to access window from a Node.js environment. This is a common error if you are:

  1. Simply looking for a global variable to use in your Node.js app
  2. Building an app that uses server-side rendering (SSR) or static site generation (SSG) with frameworks such as Gatsby.js, Nuxt.js, or Next.js. You may think that you are writing frontend code so the window object is available but the code is actually being run on the server first which causes the error, typically at build time.

💡

SSR and SSG frameworks typically go through a pre-render step when they build your app. This important step renders as much HTML as possible and runs much of your JavaScript code on the server in order to improve performance. The process of picking up where this step left off on the frontend is called hydration and is supported in both Vue and React.

The Solution

Fixing a window is not defined error can be quite simple. In most cases, all you will need to do is wrap your window associated code in logic to make sure it is only used on the client. For example, let’s say you want to get a page’s width and height:

let width = 0, height = 0;

width = window.innerWidth;
height = window.innerHeight;

Wrap this code in a check to see make sure window is defined and that error will no longer be a problem.

if (typeof window !== «undefined») {
width = window.innerWidth;
height = window.innerHeight;
}

console.log(width); // 0 if on the server, window width if on the client
console.log(height); // 0 if on the server, window height if on the client

If you are specifically working on a Node.js application and still receive this error, it is because the window object does not actually exist in a Node.js environment. To resolve this, all you would need to do is swap out your usage of window with the globalThis object. This object essentially performs the same role in Node.js that window plays while working directly with a web page: it gives you access to a global variable (among other things of course).

window.foo = «bar»; // replace this
globalThis.foo = «bar»; // with this

It’s worth mentioning that you could also reevaluate if you truly need a global object like globalThis or window in your Node.js application. You could avoid the problem altogether by defining your variable in one module and importing it wherever you need it.

// foo.js
const foo = «bar»;

module.exports = {
foo,
};

// needsFoo.js
const { foo } = require(«./foo»);

console.log(foo); // ‘bar’

Or, if you prefer the ES6+ method:

// ES6+
// foo.js
export const foo = «bar»;

// needsFoo.js
import { foo } from «./foo.js»;
console.log(foo); // ‘bar’

Between both solutions you should now be enjoying a programming experience without any window is not defined errors. If a new error comes up feel free to check out our archive for a solution or leave a comment if we haven’t covered it yet. Thanks for reading!

Возможно, вам также будет интересно:

  • Window 8 x64 ошибка установки
  • Window 7 ошибка обновления код 80070103
  • Window 7 vpn ошибка 807
  • Wincc при установке ошибка sql
  • Wincad вызвал общую ошибку защиты в модуле win87em dll

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии