如何在Next.js项目中全局集成marker.io外部脚本并正常运行?
Next.js 全局集成 marker.io 脚本的正确实现方式
核心问题说明:运行失败大概率是脚本加载顺序错误,window.markerConfig 必须在 marker.io 主脚本加载前完成定义,同时要规避 Next.js SSR 阶段不存在 window 对象的问题。
方案1:Next.js 13+ App Router 模式
在根布局文件 app/layout.tsx 中添加如下代码:
import Script from 'next/script' export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="zh"> <body> {children} {/* 第一步:先注入marker全局配置 */} <Script id="marker-config" strategy="beforeInteractive" dangerouslySetInnerHTML={{ __html: ` window.markerConfig = { destination: 'mykeysecret', source: 'snippet' }; ` }} /> {/* 第二步:注入marker初始化脚本 */} <Script id="marker-init" strategy="beforeInteractive" dangerouslySetInnerHTML={{ __html: ` !function(e,r,a){if(!e.__Marker){e.__Marker={};var t=[],n={__cs:t};["show","hide","isVisible","capture","cancelCapture","unload","reload","isExtensionInstalled","setReporter","setCustomData","on","off"].forEach(function(e){n[e]=function(){var r=Array.prototype.slice.call(arguments);r.unshift(e),t.push(r)}}),e.Marker=n;var s=r.createElement("script");s.async=1,s.src="https://edge.marker.io/latest/shim.js";var i=r.getElementsByTagName("script")[0];i.parentNode.insertBefore(s,i)}}(window,document); ` }} /> </body> </html> ) }
方案2:Next.js Pages Router 模式
在全局入口文件 pages/_app.tsx 中添加如下代码:
import Script from 'next/script' import type { AppProps } from 'next/app' export default function App({ Component, pageProps }: AppProps) { return ( <> <Component {...pageProps} /> {/* 第一步:先注入marker全局配置 */} <Script id="marker-config" strategy="beforeInteractive" dangerouslySetInnerHTML={{ __html: ` window.markerConfig = { destination: 'mykeysecret', source: 'snippet' }; ` }} /> {/* 第二步:注入marker初始化脚本 */} <Script id="marker-init" strategy="beforeInteractive" dangerouslySetInnerHTML={{ __html: ` !function(e,r,a){if(!e.__Marker){e.__Marker={};var t=[],n={__cs:t};["show","hide","isVisible","capture","cancelCapture","unload","reload","isExtensionInstalled","setReporter","setCustomData","on","off"].forEach(function(e){n[e]=function(){var r=Array.prototype.slice.call(arguments);r.unshift(e),t.push(r)}}),e.Marker=n;var s=r.createElement("script");s.async=1,s.src="https://edge.marker.io/latest/shim.js";var i=r.getElementsByTagName("script")[0];i.parentNode.insertBefore(s,i)}}(window,document); ` }} /> </> ) }
额外注意事项
- 调用 Marker 相关API前,需要先判断运行环境是否存在
window.Marker对象,避免服务端渲染阶段报错:if (typeof window !== 'undefined' && window.Marker) { window.Marker.show() } - 请将代码中的
mykeysecret替换为你自己的 marker.io 项目密钥。 - 配置
strategy="beforeInteractive"可以保证脚本在页面可交互前就完成加载,所有页面都能正常访问Marker对象。
内容的提问来源于stack exchange,提问作者Kaherdin
相关产品推荐
相关产品推荐

