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

如何将Trailforks第三方Widget转换为Next.js组件?(尝试后无效果)

在Next.js中嵌入Trailforks Region Info Widget的问题与解决

问题背景

我需要在Next.js应用中集成Trailforks的Region Info Widget,该Widget在纯HTML文件中可正常运行,但移植到Next.js组件后完全没有显示,检查元素面板也找不到相关脚本的痕迹,推测脚本未成功加载到页面中。

原始Widget代码(纯HTML可正常运行)

<!-- TRAILFORKS WIDGET START -->
<div class="TrailforksRegionInfo" data-w="435px" data-h="150px" data-rid="6253" data-counts="1" data-stats="1" data-title="1" data-activitytype="1"></div>

<script type="application/javascript" src="https://es.pinkbike.org/326/sprt/j/trailforks/iframeResizer.min.js"></script>
<script type="text/javascript">
var script = document.createElement("script"); script.setAttribute("src", "https://es.pinkbike.org/ttl-86400/sprt/j/trailforks/widget.js"); document.getElementsByTagName("head")[0].appendChild(script); var widgetCheck = false;
</script>
<!-- TRAILFORKS WIDGET END -->

我尝试的Next.js组件代码(无显示)

import Head from "next/head"

export default function RegionInfo() {
    return <div className="h-96 w-96 bg-black">
        <Head>
            <script type="application/javascript" src="https://es.pinkbike.org/326/sprt/j/trailforks/iframeResizer.min.js"></script>
            <script type="text/javascript" dangerouslySetInnerHTML={{
                __html: `
    var script = document.createElement("script"); script.setAttribute("src", "https://es.pinkbike.org/ttl-86400/sprt/j/trailforks/widget.js"); document.getElementsByTagName("head")[0].appendChild(script); var widgetCheck = false;`}}
            />
        </Head>
        <div className="TrailforksRegionInfo" data-w="435px" data-h="150px" data-rid="6253" data-counts="1" data-stats="1" data-title="1" data-activitytype="1"></div>
    </div>
}

解决方案

问题出在脚本加载的时机和Next.js的渲染机制上:直接在Head组件的dangerouslySetInnerHTML中动态创建脚本,可能因为服务端渲染时没有document对象,或者脚本加载逻辑未正确触发。

修正后的组件代码如下,使用useEffect确保脚本在客户端环境下加载,并且保证依赖脚本先加载完成:

import { useEffect } from 'react';

export default function RegionInfo() {
  useEffect(() => {
    // 先加载iframeResizer脚本
    const iframeResizerScript = document.createElement('script');
    iframeResizerScript.src = 'https://es.pinkbike.org/326/sprt/j/trailforks/iframeResizer.min.js';
    iframeResizerScript.type = 'application/javascript';
    
    // 加载完成后再加载widget脚本
    iframeResizerScript.onload = () => {
      const widgetScript = document.createElement('script');
      widgetScript.src = 'https://es.pinkbike.org/ttl-86400/sprt/j/trailforks/widget.js';
      widgetScript.type = 'text/javascript';
      document.head.appendChild(widgetScript);
    };
    
    document.head.appendChild(iframeResizerScript);

    // 清理函数,组件卸载时移除脚本
    return () => {
      document.head.removeChild(iframeResizerScript);
      const widgetScript = document.querySelector('script[src="https://es.pinkbike.org/ttl-86400/sprt/j/trailforks/widget.js"]');
      if (widgetScript) document.head.removeChild(widgetScript);
    };
  }, []);

  return (
    <div className="h-96 w-96 bg-black">
      <div className="TrailforksRegionInfo" data-w="435px" data-h="150px" data-rid="6253" data-counts="1" data-stats="1" data-title="1" data-activitytype="1"></div>
    </div>
  );
}

关键说明

  • 使用useEffect钩子,第二个参数传空数组确保只在组件挂载时执行一次,且仅在客户端运行。
  • 通过onload事件保证iframeResizer.min.js加载完成后再加载widget.js,避免依赖问题。
  • 添加清理函数,在组件卸载时移除脚本,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Igor L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:27:05