3

Leaflet is imported in a file that's imported into a client component, so why is the server running it and throwing this error?

It actually does work after a retry and eventually renders site fine.

I tried using a dynamic import inside useEffect... no dice.


ReferenceError: window is not defined
    at eval (webpack-internal:///(sc_client)/./node_modules/leaflet/dist/leaflet-src.esm.js:305:17)
    at Object.(sc_client)/./node_modules/leaflet/dist/leaflet-src.esm.js (path/to/app.next/server/app/page.js:473:1)
    at __webpack_require__ (path/to/app.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///(sc_client)/./src/js/index.js:5:89)
    at Object.(sc_client)/./src/js/index.js (path/to/app.next/server/app/page.js:1845:1)
    at __webpack_require__ (path/to/app.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///(sc_client)/./src/components/Foo.jsx:9:70)
    at Object.(sc_client)/./src/components/Foo.jsx (path/to/app.next/server/app/page.js:1834:1)

# more logs ...
// app/page.js

import Foo from '@components/Foo';

export default function Base() {
  return (
    <main>
      <Foo />
    </main>
  );
}
// components/Foo.jsx

'use client';

import { useEffect } from 'react';
import { test } from '../js/index.js';

export default function Foo() {
  useEffect(() => {
    test();
  }, []);
  return <div>foo</div>;
}


// js/index.js

// Error thrown here cause calling window
import * as L from 'leaflet/dist/leaflet-src.esm.js';

const test = () => {
  console.log(L);
};

export { test };


orangesoda
  • 97
  • 1
  • 8

1 Answers1

0

The reason for the server error in the client component is described well in a comment in Next.js repository discussion:

There's confusion about the client directive. It means that this component, also runs on the client. I've seen a lot of material out there which says only. Rather client components are like the components we wrote before. In order to send a full HTML frame from the server, client components run on the server too!

When you tried the dynamic import did you specify the ssr: false option? Here's an except from the Next.js documentation's With no SSR chapter:

To dynamically load a component on the client side, you can use the ssr option to disable server-rendering. This is useful if an external dependency or component relies on browser APIs like window.

import dynamic from 'next/dynamic';
 
const DynamicHeader = dynamic(() => import('../components/header'), {
  ssr: false,
});
Samuli Asmala
  • 1,755
  • 18
  • 24