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

Next.js 13使用bulma-calendar遇window未定义问题求助

Next.js 13 解决 bulma-calendar 服务端执行导致 window is not defined 错误问题

问题背景

使用Next.js 13集成bulma-calendar时,出现服务端渲染报错:ReferenceError: window is not defined。原因是bulma-calendar在导入阶段就会执行依赖window的初始化代码,即使将初始化逻辑放在useEffect中,全页刷新时服务端仍会执行导入操作导致报错;仅代码修改触发快速刷新时正常,因为此时客户端已加载完成。尝试用next/script加载库,但无法直接从node_modules打包脚本,且加载后无法获取bulmaCalendar变量。

解决方案(无需手动处理脚本文件)

1. 动态导入(推荐)

利用Next.js的动态导入特性,将bulma-calendar的加载推迟到客户端执行,避免服务端触发依赖window的代码。

import React, { useEffect } from 'react';

const Sample = () => {
  useEffect(() => {
    const initCalendar = async () => {
      // 仅在客户端动态导入库
      const bulmaCalendarModule = await import('bulma-calendar/dist/js/bulma-calendar.min.js');
      bulmaCalendarModule.default.attach('#calendar', {});
    };
    initCalendar();
  }, []);

  return (
    <main>
      <form>
        <input id="calendar" type="date" />
      </form>
    </main>
  );
};

export default Sample;

2. 客户端组件标记(App Router 专属)

如果使用Next.js 13 App Router,在组件顶部添加'use client'指令,强制整个组件仅在客户端渲染,所有导入和代码逻辑都不会在服务端执行。

'use client';
import React, { useEffect } from 'react';
import bulmaCalendar from 'bulma-calendar/dist/js/bulma-calendar.min.js';

const Sample = () => {
  useEffect(() => {
    bulmaCalendar.attach('#calendar', {});
  }, []);

  return (
    <main>
      <form>
        <input id="calendar" type="date" />
      </form>
    </main>
  );
};

export default Sample;

3. 同步加载结合客户端环境判断

使用require在useEffect内同步加载库,同时通过typeof window !== 'undefined'确保仅在客户端执行。

import React, { useEffect } from 'react';

const Sample = () => {
  useEffect(() => {
    if (typeof window !== 'undefined') {
      const bulmaCalendar = require('bulma-calendar/dist/js/bulma-calendar.min.js');
      bulmaCalendar.default.attach('#calendar', {});
    }
  }, []);

  return (
    <main>
      <form>
        <input id="calendar" type="date" />
      </form>
    </main>
  );
};

export default Sample;

原理说明

  • 动态导入:通过await import()让模块加载逻辑仅在客户端useEffect中执行,服务端不会处理该导入操作。
  • 客户端组件标记:'use client'告诉Next.js该组件无需服务端渲染,所有代码都在浏览器环境中运行,自然可以访问window。
  • 环境判断:通过检查window是否存在,确保依赖浏览器环境的代码仅在客户端执行,避免服务端报错。

内容的提问来源于stack exchange,提问作者Роман Коптев

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:25:01