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

Next.js 14应用无法添加2个以上Adsterra广告横幅问题求助

Next.js14中多Adsterra广告横幅无法正常显示的解决方法

问题原因

第一个广告无法显示的核心问题是全局变量冲突:两个组件都在全局作用域定义了atOptions变量,第二个组件的脚本执行时会直接覆盖第一个的配置,导致第一个广告加载时使用了错误的尺寸参数。另外,重复加载invoke.js脚本也会引发执行顺序混乱,进一步加剧问题。

解决方案

1. 避免全局变量污染

不要直接在全局作用域赋值atOptions,改用自执行函数包裹配置,确保每个广告的参数独立不被覆盖。

2. 仅加载一次广告脚本

invoke.js只需要加载一次,重复加载会造成不必要的冲突,可通过全局标记判断脚本是否已加载完成。

3. 复用组件逻辑

将两个广告组件合并为通用组件,减少重复代码的同时,统一处理脚本加载和配置初始化逻辑。

修改后的代码示例

通用Adsterra横幅组件

"use client";

import classNames from "classnames";
import { HTMLAttributes, useEffect, useRef } from "react";

interface AdsterraBannerProps extends HTMLAttributes<HTMLDivElement> {
  adKey: string;
  width: number;
  height: number;
}

const AdsterraBanner = ({ className, adKey, width, height }: AdsterraBannerProps) => {
  const container = useRef<HTMLDivElement>(null);
  const isWindow = typeof window !== "undefined";

  useEffect(() => {
    if (!isWindow || !container.current || container.current.firstChild) return;

    // 检查invoke.js是否已加载
    const scriptLoaded = window.document.querySelector(`script[src*="${adKey}/invoke.js"]`);

    // 用自执行函数包裹配置,避免全局变量覆盖
    const confScript = document.createElement("script");
    confScript.textContent = `
      (function() {
        const atOptions = ${JSON.stringify({
          key: adKey,
          format: "iframe",
          height,
          width,
          params: {},
        })};
        window.atOptions = atOptions;
        // 如果脚本已初始化,手动触发当前广告渲染
        if (typeof window.__adsterra_invoke__ === 'function') {
          window.__adsterra_invoke__();
        }
      })();
    `;
    container.current.appendChild(confScript);

    // 仅在脚本未加载时添加invoke.js
    if (!scriptLoaded) {
      const invokeScript = document.createElement("script");
      invokeScript.type = "text/javascript";
      invokeScript.src = `//www.topcreativeformat.com/${adKey}/invoke.js`;
      invokeScript.async = true;
      window.document.body.appendChild(invokeScript);
    }
  }, [isWindow, adKey, width, height]);

  return (
    <div
      ref={container}
      className={classNames("flex items-center justify-center", className)}
    />
  );
};

export default AdsterraBanner;

页面中使用组件

直接传入不同的尺寸参数即可渲染不同规格的广告:

import AdsterraBanner from "./AdsterraBanner";

export default function HomePage() {
  return (
    <div className="min-h-screen">
      {/* 468x60规格广告 */}
      <AdsterraBanner adKey="abc" width={468} height={60} className="my-4" />
      {/* 728x90规格广告 */}
      <AdsterraBanner adKey="abc" width={728} height={90} className="my-4" />
    </div>
  );
}

额外注意事项

  • 若使用next/script组件,同样需要将配置放在组件内部闭包中,避免全局变量被覆盖。
  • 部分广告平台的脚本依赖全局变量的时效性,需确保当前广告的配置在脚本执行时是正确的参数。

内容的提问来源于stack exchange,提问作者Abid Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:35:13