react leaflet map error in server side rendering
Asked Answered
T

2

6

RESOLVED --- please read update 2

hello I've this error in react starter kit with react-leaflet map

it's like github module example but i dont know what is problem!!! i think it have a problem with SSR

react version: 16.x and react starter kit

UPDATED 1

ReferenceError: window is not defined
    at D:\project\react-starterkit\node_modules\leaflet\src\core\Util.js:217:24
    at version (D:\project\react-starterkit\node_modules\leaflet\dist\leaflet-src.js:7:65)
    at Object.<anonymous> (D:\project\react-starterkit\node_modules\leaflet\dist\leaflet-src.js:10:2)
    at Module._compile (module.js:635:30)
    at Module._extensions..js (module.js:646:10)
    at Object.require.extensions.(anonymous function) [as .js] (D:\project\react-starterkit\node_modules\babel-register\lib\node.js:152:7)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)

Resolved with update react to latest version 16.x

TypeError: (0 , _react.createContext) is not a function
    at Object.<anonymous> (D:\project\react-starterkit\node_modules\react-leaflet\lib\context.js:18:47)
    at Module._compile (module.js:635:30)
    at Module._extensions..js (module.js:646:10)
    at Object.require.extensions.(anonymous function) [as .js] (D:\project\react-starterkit\node_modules\babel-register\lib\node.js:152:7)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (D:\project\react-starterkit\node_modules\react-leaflet\lib\index.js:5:16)

here is my code:

import React from 'react';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Home.css';

class Home extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    }
  }
  render() {
    const position = [this.state.lat, this.state.lng]
    return (
      <Map center={position} zoom={this.state.zoom}>
        <TileLayer
          attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <Marker position={position}>
          <Popup>
            A pretty CSS3 popup. <br /> Easily customizable.
          </Popup>
        </Marker>
      </Map>
    );
  }
}

export default withStyles(s)(Home);

UPDATE 2 Resolved by myself

import React from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import leafletCss from '!isomorphic-style-loader!css-loader?modules=false!leaflet/dist/leaflet.css'; //if use isomorphic-style-loader
import s from './GenerateMap.css';

let RL = false;
let Map = false;
let TileLayer = false;
let Marker = false;
let Popup = false;
if (process.env.BROWSER) {
  RL = require('react-leaflet');
  Map = RL.Map;
  TileLayer = RL.TileLayer;
  Marker = RL.Marker;
  Popup = RL.Popup;
}

class GenerateMap extends React.Component {
  render() {
    const position = [51.505, -0.09]

    return (
      <div className={s.root}>
        {process.env.BROWSER && (
          <Map style={{width:'100%',height: '500px'}} center={position} zoom={13}>
            <TileLayer
              url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
              attribution="&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
            />
            <Marker position={position} icon=''>
              <Popup>A pretty CSS3 popup.<br />Easily customizable.</Popup>
            </Marker>
          </Map>
        )}
      </div>
    );
  }
}

export default withStyles(s, leafletCss)(GenerateMap);
Taeniasis answered 10/7, 2018 at 12:26 Comment(4)
You get this error on server side ? or in browser ?Parathion
on server side renderingTaeniasis
you can return null; if typeof window === 'undefined' so it will render Map only on client side.Parathion
ok i know i can use typeof or process.env.BROWSER but it's a npm module and i cant change itTaeniasis
P
6

From the stack traces, I see that react-leaflet is using createContext() which is part of React Context API. This is only available in React 16.3.

Have you checked the version of react-leaflet you are using? You might be using version that have dependency to React 16.3. You could try downgrading to react-leaflet 1.9.1 and see if it works.

Updated answer:

window is not defined is an error that most likely happened when your code is trying to access the global variable window which is only defined when your code run in browser (not SSR). Check your code to see if that error happened because of your code. If it is caused by react-leaflet, read below...

After more searching, it seems that react-leaflet isn't built with server side rendering in mind. You could try checking react-leaflet-universal to implement it. If all else fail, you might need to build your own wrapper for leaflet to achieve this.

Pentagon answered 10/7, 2018 at 13:1 Comment(2)
thank you it's correct but now i've this error ReferenceError: window is not defined! it's for SSR how can load it for CSR?Taeniasis
For Client Side Rendering, you have to wait till the component is mounted. I haven't tested this, but I wonder if ComponentDidMount might work.Gulledge
U
1

Using Nextjs with dynamic import:

const DynamicMap = dynamic(() => import("@/components/MapComponent"), { ssr: false });

return (
    <div>
      {/* Load immediately */}
      <DynamicMap />
    <div />
)
Unproductive answered 15/8, 2024 at 20:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.