I'm trying to add a react-leaflet
map to a remix app. I created a simple app using the npx create-remix@latest
command. I then added react-leaflet
using the installation instructions. Now I have the following code:
index.tsx
import type { MetaFunction } from "@remix-run/node";
import { ClientOnly } from "remix-utils/client-only";
import LazyMap from "~/components/LazyMap";
export const meta: MetaFunction = () => {
return [
{ title: "New Remix App" },
{ name: "description", content: "Welcome to Remix!" },
];
};
export default function Index() {
return (
<div>
test 123
<ClientOnly fallback={<p>Loading...</p>}>
{() => <LazyMap />}
</ClientOnly>
</div>
);
}
LazyMap.tsx
import { Suspense, lazy } from 'react';
const Map = lazy(() => import('./Map'));
export default function LazyMap() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Map />
</Suspense>
);
}
Map.tsx
import { MapContainer } from 'react-leaflet/MapContainer'
// import { Marker } from 'react-leaflet/Marker'
// import { Popup } from 'react-leaflet/Popup'
// import { TileLayer } from 'react-leaflet/TileLayer'
import { ClientOnly } from 'remix-utils/client-only';
export default function Map() {
return (
<div>
test 123
<ClientOnly>
{() => (
<MapContainer zoom={13} scrollWheelZoom={false}>
test
</MapContainer>
)}
</ClientOnly>
</div>
);
}
Even though I've wrapped the Map
in a lazy import from LazyMap
it appears to still be trying to process the Map
file, which of course references leaflet and causes the dreaded ReferenceError: window is not defined
error. How can I overcome this error?
The ClientOnly
utility is great when rendering the component causes a reference to some client-side-only global variable like window
or document
, but it can only wrap component code you've imported, and imports can have side-effects...like referencing window
or document
.
According to the official remix docs you can add a .client.ts/tsx/js/jsx
suffix to your file to have it excluded from the SSR.