如何在Next.js App Router服务端组件中打开Supademo弹窗嵌入
解决方案
要在保持页面为服务端组件的同时实现需求,核心是将交互逻辑封装到客户端组件中,单独处理SDK加载状态和点击事件。以下是最小实现:
1. 创建客户端按钮组件
新建app/features/SupademoButton.tsx,这是一个客户端组件,负责管理SDK就绪状态和点击逻辑:
'use client'; import { useState, useEffect } from 'react'; export default function SupademoButton() { const [isSdkReady, setIsSdkReady] = useState(false); useEffect(() => { // 检查SDK是否已加载 const checkSdkReady = () => { if (window.Supademo) setIsSdkReady(true); }; // 立即检查一次 checkSdkReady(); // 监听window对象变化,确保SDK加载后及时更新状态 const observer = new MutationObserver(checkSdkReady); observer.observe(window, { attributeFilter: ['Supademo'] }); return () => observer.disconnect(); }, []); const handleOpenDemo = () => { if (isSdkReady) window.Supademo.open('DEMO_ID'); }; return ( <button type="button" onClick={handleOpenDemo} disabled={!isSdkReady} aria-disabled={!isSdkReady} > {isSdkReady ? 'View walkthrough' : 'Loading walkthrough...'} </button> ); }
2. 修改原服务端页面
保持app/features/page.tsx为服务端组件,引入新建的客户端按钮即可:
// app/features/page.tsx import Script from 'next/script'; import SupademoButton from './SupademoButton'; export default function FeaturesPage() { return ( <main> <h1>Feature overview</h1> <Script src="https://script.supademo.com/supademo.js" strategy="afterInteractive" /> <SupademoButton /> </main> ); }
关键细节
- 客户端组件隔离:通过
'use client'指令将交互逻辑限制在单独组件中,原页面保持服务端渲染特性。 - SDK就绪检测:使用
MutationObserver监听window.Supademo的加载状态,比轮询更高效;也可以替换为setInterval轮询(适合简单场景)。 - 可用性控制:按钮默认禁用,SDK就绪后才启用,同时通过文本提示用户状态,避免无效点击。
内容的提问来源于stack exchange,提问作者Gavin W
相关产品推荐
相关产品推荐

