-
Notifications
You must be signed in to change notification settings - Fork 29.9k
Description
Say you wanted to render some maps in your Next application. You chose the fairly popular react-leaflet project, which takes the very popular leaflet library... and React-izes it.
It turns out that Leaflet is in fact not ready for an isomorphic application, as it has things like window and navigator all over its codebase. This is turn causes Next to crash with a sad ReferenceError: window is not defined.
You can't use conditional logic in your map component because include statements need to happen at the top of the file, and at boot. You can change from include to require (and require conditionally), but that seems like a bad idea, and Next throws a warning (below). You can block rendering a map on the server, but not the inclusion of the react-leaflet => react libraries.
The warning Next throws when using a conditional required:
Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) react-empty: 27 --><!-- react-empty: 28
(server) react-empty: 27 --><p data-reactid="28">
It's fairly easy to check if you are running on the sever or client:
export default function isNode(){
// http://stackoverflow.com/questions/4224606/how-to-check-whether-a-script-is-running-under-node-js
return (typeof process !== 'undefined') && (process.release) && (process.release.name === 'node');
};How should we handle something like this? I could imagine a try/catch scenario when rendering on the server looking for specifically window, navigator, etc and rendering a small ./pages/_unrenderable.js in those components.... but that seems... hacky.