(Webpack) Why am I getting ReferenceError: self is not defined in Next.js when I try to import a client-side library?

Total
3
Shares

Trying to create an xterm react component in Next.js I got stuck as I’m not able to get over an error message I’ve never got before.

I’m trying to import a npm client-side module called xterm, but if I add the import line the aplication crashes.

import { Terminal } from 'xterm'

The error reads Server Error... ReferenceError: self is not defined
and then shows this chunk of code as Source

module.exports = require("xterm");

According to some research I did, this has to do with Webpack and could be helped if something like this was done:

output: {
  globalObject: 'this'
}

Would you know how to fix this? Thank you in advance! 🤪


Solution

The error occurs because xterm tries to access the window object which is not available on the server-side. To fix it, you can dynamically import xterm with ssr: false so it only gets loaded on the client-side.

import dynamic from 'next/dynamic'

const Terminal = dynamic(
    {
        loader: () => import('xterm').then((mod) => mod.Terminal),
        render: (props, Terminal) => {
            const term = new Terminal()
            // Add logic with `term`
            return <></>
        }
    },
    {
        ssr: false
    }
)

Edit: As an alternative, you could create a new component where you’d import xterm.

// components/terminal-component
import { Terminal } from 'xterm'

function TerminalComponent() {
    const term = new Terminal()
    // Add logic around `term`
    return <></>
}

export default TerminalComponent

Then dynamically import the component when using it.

import dynamic from 'next/dynamic'

const TerminalComponent = dynamic(() => import('<path-to>/components/terminal-component'), {
    ssr: false
})
Leave a Reply

Your email address will not be published. Required fields are marked *