Dynamic Import Node Module With Next.js

Viewed 25072

I was getting an error of window undefined when using react-leaflet node module because it relies on window and of course SSR does not support window. I found next/dynamic, however, all the examples I found show how to import a component and not a node module. Is it possible to include a node module and if so how? As an example this is what I'm importing that is giving the window undefined error import { Map, TileLayer, Marker } from 'react-leaflet';

4 Answers

A better way of getting named exports with a dynamic import is to do this:

const NamedExport = dynamic(() => import('package-name').then((module) => module.NamedExport));

Note: this will chunk the full 'package-name' package and then simply extract the named export. If you are able to path into the module package like the accepted example, that will probably be better as it will likely give you a smaller chunk.

That error happened when you call that dependency's component (Map, TileLayer, Marker) on your component.

Window of undefined occured when your application is being rendered on server side, because window object is belong to the browser.

To avoid error of window of undefined on server side, you can use process.browser in your component.

ref: https://github.com/zeit/next.js/issues/2473?#issuecomment-362119102

I kept hitting type definition issues with the accepted answer, and I didn't want to import the whole library. This is what I came up with:

reexport/index.ts:

export { Marker, /* any other type you'll need */ } from 'react-leaflet';

Then, in your component/page, simply import anything from the module above.

const Marker = useMemo(() => dynamic<MarkerProps>(
    () => import('./reexport').then(re => re.Marker),
    { ssr: false }
), []);

Note that I've wrapped the call to dynamic in a useMemo hook, and also provided a type for the props.

Related