2

I'm trying to playing around with React. I followed the "Getting Started" tutorial of NextJs (link) and I have successfully created the new project.

As soon as I try to import third-party plugins like current-devices or smooth-scrollbar I get the following error:

ReferenceError: window is not defined
(anonymous function)
/c/xampp/htdocs/nextjs/node_modules/smooth-scrollbar/dist/smooth-scrollbar.js:1:262
Module._compile
module.js:652:30
Module._extensions..js
module.js:663:10
Module.load
module.js:565:32
tryModuleLoad
module.js:505:12
Function.Module._load
module.js:497:3
Module.require
module.js:596:17
require
internal/module.js:11:18
smooth-scrollbar
webpack:/external "smooth-scrollbar":1
> 1 | module.exports = require("smooth-scrollbar");
View compiled
__webpack_require__
./webpack/bootstrap:21
  18 | // Execute the module function
  19 | var threw = true;
  20 | try {
> 21 |  modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     | ^  22 |  threw = false;
  23 | } finally {
  24 |  if(threw) delete installedModules[moduleId];
View compiled
Module../pages/index.js
/_next/development/server/static/development/pages/index.js:221:74
__webpack_require__
./webpack/bootstrap:21
  18 | // Execute the module function
  19 | var threw = true;
  20 | try {
> 21 |  modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     | ^  22 |  threw = false;
  23 | } finally {
  24 |  if(threw) delete installedModules[moduleId];
View compiled
3
/_next/development/server/static/development/pages/index.js:383:18
__webpack_require__
./webpack/bootstrap:21
  18 | // Execute the module function
  19 | var threw = true;
  20 | try {
> 21 |  modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     | ^  22 |  threw = false;
  23 | } finally {
  24 |  if(threw) delete installedModules[moduleId];
View compiled
▶ 2 stack frames were collapsed.

The import I made in the file C:\xampp\htdocs\nextjs\pages\index.js

is just:

import Scrollbar from 'smooth-scrollbar';
import device from 'current-device'

Thanks a lot for the help!

2 Answers 2

13

Next.js has a server-side and a client-side, window is not defined in server-side,'smooth-scrollbar' and 'current-device' probably use window both, you can use dynamic import of next with ssr: false for just using some package in clinet-side:

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(
  () => import('package'),
  { ssr: false }
)

// ...


// use it in render like:
<DynamicComponentWithNoSSR />

for more info visit docs

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer! I was not considering the server-side rendering and the client-side rendering!
Short, sweet, and works. Couldn't ask for more, thank you :)
@SamSverko Happy to help :)
Thanks so much, I have window location error sometimes and I didn't know why! It was simple and great!
great! your answer also worked for this error Next.js SyntaxError "Unexpected token 'export'": stackoverflow.com/q/65936222/3051080
5

In my case, doing Nextjs Dynamic import was not enough.

EXAMPLE

Imported TVChart.js Dynamically

import dynamic from "next/dynamic"
import * as React from "react"

const TVChartContainer = dynamic(() => import("./TVChart"), { ssr: false })

export default () => {
  return <TVChartContainer />
}

If you are still getting > ReferenceError: window is not defined error even after using dynamic imports with no ssr as mentioned in the accepted answer, then it might be due to the dependency which requiring window be present and is imported at the top level.

In my case I was importing TradingView Charting Library widget object like this:

TVChart.js - Not working

import { widget } from "../public/static/charting_library/charting_library.min" //did not work

class TVChart extends Component {

    tvWidget = null

    componentDidMount() {
        const widgetOptions = {} //ChartingLibraryWidgetOptions
        this.tvWidget = new widget(widgetOptions)
    }

    render() {
        <div id="tv_chart_container" className="TVChartContainer" />
    }
}
export default TVChart;

TVChart.js - Working

// import { widget } from "../public/static/charting_library/charting_library.min" // <-- Remove this line

class TVChart extends Component {

    tvWidget = null

    async componentDidMount() {
        const { widget } = await import("../public/static/charting_library/charting_library.min") // <-- Import asynchronously
        const widgetOptions = {} //ChartingLibraryWidgetOptions
        this.tvWidget = new widget(widgetOptions)
    }

    render() {
        <div id="tv_chart_container" className="TVChartContainer" />
    }

}
export default TVChart;

Hope it Helps.

1 Comment

This was very helpful! Note that if you're importing an npm package, as I was, you can access the default export by destructuring it. You can event alias as something else: const { default: LibName } = await import('SomeNPMLibrary');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.