Next.js 13.5项目嵌入Calendly遇两类错误,求解决方案
解决Next.js 13.5中嵌入Calendly的两种错误问题
问题1:官方脚本调用window.Calendly.initInlineWidget报错
错误原因
异步加载的Calendly脚本未完成加载时,useEffect就直接调用window.Calendly,导致读取initInlineWidget时出现undefined。同时在Next.js 13.5的App Router中,直接用Head组件嵌入脚本的方式,不如官方Script组件能精准控制加载时机。
修复方案
使用Next.js的next/script组件替代原生script标签,通过onLoad回调确保脚本加载完成后再初始化组件:
"use client"; import Script from "next/script"; import React, { useRef } from "react"; export default function Calendly() { const calendlyRef = useRef(null); const initCalendly = () => { if (window.Calendly && calendlyRef.current) { window.Calendly.initInlineWidget({ url: "你的Calendly链接", parentElement: calendlyRef.current, }); } }; return ( <> <Script src="https://assets.calendly.com/assets/external/widget.js" strategy="afterInteractive" onLoad={initCalendly} /> <div ref={calendlyRef} style={{ minWidth: 320, height: 580 }} data-auto-load="false" ></div> </> ); }
也可以手动创建脚本并监听加载状态,不依赖Script组件:
"use client"; import React, { useEffect, useRef } from "react"; export default function Calendly() { const calendlyRef = useRef(null); useEffect(() => { const script = document.createElement("script"); script.src = "https://assets.calendly.com/assets/external/widget.js"; script.async = true; script.onload = () => { if (calendlyRef.current) { window.Calendly.initInlineWidget({ url: "你的Calendly链接", parentElement: calendlyRef.current, }); } }; document.body.appendChild(script); return () => { document.body.removeChild(script); }; }, []); return ( <div ref={calendlyRef} style={{ minWidth: 320, height: 580 }} data-auto-load="false" ></div> ); }
问题2:使用react-calendly库时报错Object prototype may only be an Object or null: undefined
错误原因
该错误多因react-calendly版本与Next.js 13.5(React 18)的App Router不兼容,或是在服务器组件中直接引入客户端专用库组件,也可能是依赖冲突导致原型链异常。
修复方案
- 标记为客户端组件:在使用
react-calendly的组件顶部添加"use client";指令,避免服务器端渲染时执行客户端代码。 - 升级库版本:更新
react-calendly到最新版本,确保兼容React 18和Next.js App Router:
npm update react-calendly # 或 yarn upgrade react-calendly
- 动态导入组件:若升级后仍有问题,用React的
lazy和Suspense动态导入组件:
"use client"; import React, { lazy, Suspense } from "react"; const InlineWidget = lazy(() => import("react-calendly").then(mod => ({ default: mod.InlineWidget }))); export default function Calendly() { return ( <Suspense fallback={<div>加载中...</div>}> <InlineWidget url="你的Calendly链接" styles={{ minWidth: "320px", height: "580px" }} /> </Suspense> ); }
- 重置依赖:若以上方法无效,删除依赖文件后重新安装:
rm -rf node_modules package-lock.json npm install
内容的提问来源于stack exchange,提问作者Emdadul Islam
相关产品推荐
相关产品推荐

