denoland / fresh

The next-gen web framework.
https://fresh.deno.dev
MIT License
12.54k stars 648 forks source link

ReferenceError: document is not defined when using @egjs/preact-flicking #1976

Closed tkovs closed 1 year ago

tkovs commented 1 year ago

The solution of #1809 didn't help me because I need the imported component.

I started a Fresh website, and I need a carousel component. For that, I chose the flicking lib. I'm trying to render a Flicking component, but the run breaks:

➜  example git:(main) ✗ deno task start

Task start deno run -A --watch=static/,routes/ dev.ts
Watcher Process started.
The manifest has been generated for 5 routes and 1 islands.
error: Uncaught (in promise) ReferenceError: document is not defined
    at https://esm.sh/v132/@egjs/preact-flicking@4.11.0/denonext/preact-flicking.mjs:2:56465
Watcher Process failed. Restarting on file change...

The current code:

// islands/Carousel.tsx
import Flicking from "https://esm.sh/@egjs/preact-flicking@4.11.0";

export const Carousel = () => <Flicking />;

Previous tries

I tried to check for typeof window !== 'undefined' before rendering the Flicking component, but it didn't work.

I also tried to use lazy imports:

import { lazy, Suspense } from "preact/compat";

const Flicking = lazy(() =>
  import("https://esm.sh/@egjs/preact-flicking@4.11.0")
);

export const Carousel = () => (
  <Suspense fallback={<p>Loading...</p>}>
    <Flicking />
  </Suspense>
);

But the initial result is a [object Promise] on the screen, and when I restart the page, the ReferenceError: document is not defined comeback. (ps.: this way, the build process doesn't break - the error appears on the page)

tkovs commented 1 year ago

I solved it by using both strategies 🤦

import { lazy, Suspense } from "preact/compat";
import { IS_BROWSER } from "$fresh/runtime.ts";

const Flicking = lazy(() =>
  import("https://esm.sh/@egjs/preact-flicking@4.11.0")
);

export const Carousel = () => {
  if (!IS_BROWSER) {
    return <p>Not browser</p>;
  }

  return (
    <Suspense fallback={<p>Loading...</p>}>
      <Flicking />
    </Suspense>
  )
);