Making Next.js and Mapbox GL JS get along

Timothy Krechel
2 min readOct 23, 2018

--

TL;DR: Mapbox GL JS does give errors when trying to render server-side. Using next’s dynamic imports and setting the optionssr: false forces client-side rendering, making this work.

Mapbox and the window object

This is going to be a very short post, but that does not make it unimportant — I just wanted to share a solution to a problem I encountered while using next.js and Mapbox.

This is not what you want!

Without diving into great detail, Mapbox GL JS uses the global window object under the hood. When rendering components server-side as we want to do using next.js, this object does not exist.

Using dynamic imports

For this, the next package comes with a method that allows us to dynamically import components that need client-side rendering.

So instead of importing and rendering your Mapbox component via:

// This is going to rekt your appimport Map from './client';export default () => (
<div>
<Map />
</div>
);

We’d rather import the method dynamic, which is a default export, from thenext/dynamic package via import dynamic from 'next/dynamic'

After this, you can dynamically import the component via:

const DynamicMap = dynamic(() => import('./client'), {
loading: () => <p>Loading...</p>
});

The dynamically loaded component is now stored in the DynamicMap variable. Note that the dynamic() method call takes a second argument with an optional options object, where we can specify a React component that’s supposed to show up before the component is rendered on the client via the loading property.

I somehow still received some errors which I resolved by also adding a ssr: false property to the options object, so my final code looked like this:

const DynamicMap = dynamic(() => import('./client'), {
loading: () => <p>Loading...</p>,
ssr: false
});

If you ran into the same trouble as I did, I hope this short post was useful for you. See you next time!

--

--