locomotivemtl / locomotive-scroll

🛤 Detection of elements in viewport & smooth scrolling with parallax.
https://locomotivemtl.github.io/locomotive-scroll
MIT License
7.55k stars 1.11k forks source link

Locomotive v5 ReferenceError: window is not defined #506

Closed tariknh closed 8 months ago

tariknh commented 1 year ago

Hello 👋

Describe the bug When using locomotive v5, npm run dev works but on build it fails with "ReferenceError: window is not defined"

To Reproduce Steps to reproduce the behavior:

  1. Add new locomotive scroll to UseEffect
  2. npm run build/dev
  3. See error: ReferenceError: window is not defined

Expected behavior Window to be defined when its called in useEffect

Thank you 👊

Lunari8546 commented 1 year ago

I found a solution in this issue, basically you need to import the module after the component mounted. In your case, you need to import it in UseEffect().

ondrejjcizek commented 11 months ago

SVELTEKIT

locomotive.ts

import LocomotiveScroll from 'locomotive-scroll';

export const locomotiveScroll = new LocomotiveScroll({
  lenisOptions: {
      wrapper: window,
      content: document.documentElement,
      lerp: 0.1,
      duration: 0.6,
      orientation: 'vertical',
      gestureOrientation: 'vertical',
      smoothWheel: true,
      smoothTouch: true,
      wheelMultiplier: 1,
      touchMultiplier: 0.5,
      normalizeWheel: true,
      easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t))
  }
});

+page.svelte

<script lang="ts">
  import { onMount } from 'svelte';

  onMount(async () => {
  const locomotive = await import('../../imports/locomotive');
  });
</script>

html

css
tariknh commented 8 months ago

Solution for NextJS/React was this

useEffect(() => {
    let scroll: import("locomotive-scroll");
    import("locomotive-scroll").then((locomotiveModule) => {
      scroll = new locomotiveModule.default();
    });

   // cleanup phase
    return () => {
      if (scroll) scroll.destroy();
    };
  });

If you want more settings you can do it inside like this:

useEffect(() => {
        let scroll: import("locomotive-scroll");
        import("locomotive-scroll").then((locomotiveModule) => {
            scroll = new locomotiveModule.default({
                el: document.querySelector("[data-scroll-container]"),
                smooth: true,
                smoothMobile: false,
                resetNativeScroll: true
            });
        });

        // cleanup phase
        return () => {
            if (scroll) scroll.destroy();
        }
    });