skip to Main Content

I am using react-leaflet in my nextjs project. The project works perfect on dev mode but when I try to build it it gives ReferenceError: window is not defined. I am also using ssr as false in dynamic but still gives the same error. Here is the code for further reference. any help would be highly appreciated. Thank you.

index.js

import dynamic from 'next/dynamic'

export default dynamic(() => import("./map"), { ssr: false });

// const  OpenStreetMap = dynamic(() => import('./map'), {
   //   ssr: false
// })

// const index = () => {
  //   return (
          //     <>
            //       <OpenStreetMap />
          //     </>
  //   )
// }

// export default index

map.js

import React, { useState, useRef, useEffect, useMemo } from 'react'
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'

const OpenStreetMap = () => {

   const [center, setCenter] = useState({ lat: 43.64701, lng: -79.39425 })
   const ZOOM_LEVEL = 5
   const mapRef = useRef()

   return (
      <MapContainer center={center} zoom={ZOOM_LEVEL} ref={mapRef} style={{ flex: 2, 
        height: '100%', width: '100%' }}>
      <TileLayer attribution='&copy; <a href="mailto:[email protected]" 
         target="_blank" rel="noopener noreferrer">Developed by Mubashir</a> &copy; <a 
             href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> 
              contributors'
             url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
      />

        <Marker
          position={position}
          icon={icon}
          eventHandlers={{
            click: () => handleMarkerClick(marker)
          }}
        />
  </MapContainer>
 )
}

export default OpenStreetMap

Error

info  - Collecting page data ..ReferenceError: window is not defined
at D:logistics-crmlogistics-crmnode_modulesleafletdistleaflet-src.js:230:19
at D:logistics-crmlogistics-crmnode_modulesleafletdistleaflet-src.js:7:66
at Object.<anonymous> (D:logistics-crmlogistics-crmnode_modulesleafletdistleaflet-src.js:10:3)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
node:internal/process/promises:288
        triggerUncaughtException(err, true /* fromPromise */);
        ^

ReferenceError: window is not defined
at D:logistics-crmlogistics-crmnode_modulesleafletdistleaflet-src.js:230:19
at D:logistics-crmlogistics-crmnode_modulesleafletdistleaflet-src.js:7:66
at Object.<anonymous> (D:logistics-crmlogistics-crmnode_modulesleafletdistleaflet-src.js:10:3)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
> Build error occurred
Error: Failed to collect page data for /apps/map/map
at D:logistics-crmlogistics- crmnode_modulesnextdistbuildutils.js:1152:15 {
type: 'Error'
}
info  - Creating an optimized production build .info  - Collecting page data .

2

Answers


  1. Chosen as BEST ANSWER

    The above answer is correct, and it is already what I had done before asking the question, so it didn't solve my problem. am writing the answer here as the above didn't solve my issue. I was using file structures like src/pages and src/views. I moved all my component files like map.js and mapComponent.js to src/views and index.js to src/pages folder. This is important as the next.js first considers pages folder. This is the link that helped me solve the problem.

    src/views/map/map.tsx

    import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
    import 'leaflet/dist/leaflet.css';
    import styles from './map.module.css';
    import L from 'leaflet'
    
    const DEFAULT_CENTER: any = [23.737704855705548, 90.40943564985567];
    const size = 5;
    
    const Map = ({ dealersList }: any) => {
    
     return (
      <MapContainer className={styles.map} center={DEFAULT_CENTER} zoom={10} 
      scrollWheelZoom={true}>
       <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
       {dealersList?.map((dealer: any, index: number) => (
        <Marker
          key={index}
          position={[dealer.latitude, dealer.longitude]}
          eventHandlers={{
            click: () => {
              console.log('marker clicked');
            }
          }}
          icon={L.divIcon({
            iconSize: [size, size],
            iconAnchor: [size / 2, size + 9],
            className: "mymarker",
            html: ``,
          })}
        >
          <Popup>
            <div>
              <p className="font-bold">{dealer.name}</p>
              <p>{dealer.address}</p>
            </div>
          </Popup>
        </Marker>
      ))}
      </MapContainer>
     );
    };
    
    export default Map;
    

    src/views/map/MapComponent.js

    import dynamic from 'next/dynamic';
    export const MapComponent = dynamic(() => import('./map'), { ssr: false });
    

    src/pages/index.ts

    import { MapComponent } from 'src/views/map/MapComponent';
    
    <div className="overflow-hidden mt-4">
      <MapComponent dealersList={dealersList} />
    </div>
    

  2. I faced the same issue. There is the way I resolved the problem as follows:

    1. Add map.module.css file
    .map {
      height: 60vh;
     }
    
    1. Export naming component as MapComponent instead of default in the index.ts file
    import dynamic from 'next/dynamic';
    export const MapComponent = dynamic(() => import('components/map/map-dealer'), { ssr: false });
    
    1. My map-dealer.tsx file is as follows
    'use client';
    
    import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
    import 'leaflet/dist/leaflet.css';
    import styles from './map.module.css';
    import L from 'leaflet'
    
    const DEFAULT_CENTER: any = [23.737704855705548, 90.40943564985567];
    const size = 5;
    
    const Map = ({ dealersList }: any) => {
    
      return (
        <MapContainer className={styles.map} center={DEFAULT_CENTER} zoom={10} scrollWheelZoom={true}>
          <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
          {dealersList?.map((dealer: any, index: number) => (
            <Marker
              key={index}
              position={[dealer.latitude, dealer.longitude]}
              eventHandlers={{
                click: () => {
                  console.log('marker clicked');
                }
              }}
              icon={L.divIcon({
                iconSize: [size, size],
                iconAnchor: [size / 2, size + 9],
                className: "mymarker",
                html: ``,
              })}
            >
              <Popup>
                <div>
                  <p className="font-bold">{dealer.name}</p>
                  <p>{dealer.address}</p>
                </div>
              </Popup>
            </Marker>
          ))}
        </MapContainer>
      );
    };
    
    export default Map;
    
    1. Import this MapComponent to the parent component
    import { MapComponent } from 'components/map';
    
    <div className="overflow-hidden mt-4">
       <MapComponent dealersList={dealersList} />
    </div>
    

    So make sure you import the styles from map.module.css because the map will be visible when hight is found and update it as needed.

    Hope it will be helpful.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search