You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jarallax在Next.js/TypeScript中报错:Cannot read properties of undefined (reading 'userAgent')

问题

基于Next.js/TypeScript复刻使用Jarallax的模板时,编译组件触发模块错误,错误信息如下:

Server Error
Error: Cannot read properties of undefined (reading 'userAgent')

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
eval
node_modules\jarallax\dist\jarallax.esm.js (131:1)
(rsc)/./node_modules/jarallax/dist/jarallax.esm.js
file:///C:/wamp64/www/_site/.next/server/vendor-chunks/jarallax.js (30:1)
Next.js
eval
/./src/app/components/About/About.tsx
(rsc)/./src/app/components/About/About.tsx
file:///C:/wamp64/www/_site/.next/server/app/page.js (195:1)
Next.js
eval
/./src/app/page.tsx
(rsc)/./src/app/page.tsx
file:///C:/wamp64/www/_site/.next/server/app/page.js (363:1)
Next.js

相同代码在纯客户端环境可正常运行,但在Next.js SSR环境中报错,不清楚如何正确引入Jarallax以及是否需要自定义组件。

原组件核心代码:

import React from 'react'
import { jarallax, jarallaxElement } from "jarallax";

const About = () => {
  React.useEffect(() => {
    jarallaxElement();
    jarallax(document.querySelectorAll("[data-jarallax-element]"));
  }, [])

  return (
    <section className="elementor-section ..." id="about">
       {/* 省略页面DOM结构 */}
    </section>
  )
}

export default About

解决方案

错误根源

Jarallax初始化时会读取window.navigator.userAgent判断浏览器环境,但Next.js默认SSR模式下,服务端没有window对象,导致读取userAgent时触发undefined错误。

修复步骤

  1. 动态导入Jarallax,限制在客户端加载
    使用React的动态导入函数,确保Jarallax仅在客户端环境初始化:
import React, { useEffect, useRef } from 'react';

const About = () => {
  const sectionRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const initJarallax = async () => {
      // 动态导入Jarallax及元素扩展
      const { jarallax, jarallaxElement } = await import('jarallax');
      jarallaxElement();
      
      // 通过ref精准获取元素,避免全局DOM查询
      if (sectionRef.current) {
        jarallax(sectionRef.current.querySelectorAll("[data-jarallax-element]"));
      }
    };

    initJarallax();

    // 清理副作用:页面卸载时销毁Jarallax实例
    return () => {
      import('jarallax').then(({ jarallax }) => {
        if (sectionRef.current) {
          sectionRef.current.querySelectorAll("[data-jarallax-element]").forEach(el => {
            jarallax(el, 'destroy');
          });
        }
      });
    };
  }, []);

  return (
    <section ref={sectionRef} className="elementor-section ..." id="about">
       {/* 保留原页面DOM结构 */}
    </section>
  )
};

export default About;
  1. 封装可复用Jarallax组件(可选)
    如果多个页面需要使用Jarallax,可封装通用组件简化调用:
// components/JarallaxElement.tsx
import React, { useEffect, useRef, PropsWithChildren } from 'react';

interface JarallaxElementProps {
  speedX?: number;
  speedY?: number;
  className?: string;
}

const JarallaxElement: React.FC<PropsWithChildren<JarallaxElementProps>> = ({
  speedX = 0,
  speedY = 0,
  className,
  children
}) => {
  const elementRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const initJarallax = async () => {
      const { jarallax, jarallaxElement } = await import('jarallax');
      jarallaxElement();

      if (elementRef.current) {
        jarallax(elementRef.current, {
          type: 'element',
          speed: [speedX, speedY]
        });
      }
    };

    initJarallax();

    return () => {
      import('jarallax').then(({ jarallax }) => {
        if (elementRef.current) {
          jarallax(elementRef.current, 'destroy');
        }
      });
    };
  }, [speedX, speedY]);

  return (
    <div
      ref={elementRef}
      className={className}
      data-jarallax-element={`${speedX} ${speedY}`}
    >
      {children}
    </div>
  );
};

export default JarallaxElement;

调用示例:

<JarallaxElement speedX={0} speedY={-30} className="elementor-element ...">
  {/* 图片或内容 */}
</JarallaxElement>
  1. 直接禁用组件SSR(极端场景)
    若上述方法无效,可通过Next.js的dynamic函数强制组件仅在客户端渲染:
// page.tsx
import dynamic from 'next/dynamic';

const About = dynamic(() => import('./components/About/About'), {
  ssr: false
});

export default function Home() {
  return <About />;
}

内容的提问来源于stack exchange,提问作者The Old County

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:59:52