Paul Laskowski
Paul Laskowski

Reputation: 33

Mapbox-gl.js and server side rendering Reference Error: self is not defined

Our application is a React/Node app built with Webpack and renders server side in production. In this production scenario, the mapbox-gl package has a problem loading on the server side. I suspect this has something to do with the way mapbbox-gl.js is an already browserified library, and doesn't play well with this server side environment that is built with webpack. Below is the relevant error when I try to load the page for the first time and we don't get any of the component's html generated on the server side (though everything works when it then loads in the browser client).

The relevant line of code in mapbox-gl.js that generates the error at the top of the stack reads "module.exports=self;".

    Node app is running on port 5000
ReferenceError: self is not defined
    at Object.112 (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:225:29)
    at s (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:1:602)
    at eval (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:1:653)
    at Object.110../window (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:221:25)
    at s (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:1:602)
    at eval (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:1:653)
    at Object.24.../package.json (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:48:26)
    at s (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:1:602)
    at e (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:1:773)
    at eval (webpack:///./~/mapbox-gl/dist/mapbox-gl.js?:1:791)

Hopefully there are some tweaks I can add to our webpack build config to make this work. Sorry there isn't a lot of info here, I'm hoping that someone has come across this problem and there might be an easy fix.

Upvotes: 2

Views: 4400

Answers (2)

Abdelsalam Shahlol
Abdelsalam Shahlol

Reputation: 1759

I was facing the same problem on Nuxt.js. In order to solve this problem the mapbox package should be imported on the client side only.

Here's the code:

let mapboxgl;

// Check if the process is on the client side
if (process.client) {
  mapboxgl = require('mapbox-gl');
}

Upvotes: 0

David Guan
David Guan

Reputation: 4290

Actually, when it comes to server-side rendering, this kind of scenario is very common which is some library rely on DOM exist or browser environment.

Solution:
1. In the webpack configuration, define a variable for indicating whether the application is running on server side.

new webpack.DefinePlugin({
  __CLIENT__: true
  // Other global variables
}), 

2. Inside the files that using the mapbox library

let mapboxGl;
if (__CLIENT__) {
  mapboxGl = require('mapbox-gl')
}

3. Server side entry code

global.__CLIENT__ = false;

4. For using webpack for both client-side and server-side, using webpack-isomorphic-tools

Upvotes: 6

Related Questions