更新:GPT 广告实施(React 应用程序)的问题已部分修复

问题描述 投票:0回答:1

我正在尝试在我的 React 应用程序新闻源上返回测试广告,但 NPM 似乎缺乏文档。我唯一能找到的东西是来自 eBayClassifiedsGroup/react-advertising。这是我的第 1 步代码(参见第 46-54 行):

import React, { Component } from 'react';
import './App.css';
import News from './News/News';
import SideFeed from './News/SideFeed';
import {
  AdvertisingProvider,
  AdvertisingSlot,
} from 'react-advertising';
import config from './News/config'



class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      news1: {
        type: 'top-headlines',
        query: 'sources=bbc-news'
      },
      news2: {
        type: 'everything',
        query: 'domains=techcrunch.com&language=en'
      },
      news3: {
        type: 'everything',
        query: 'domains=comicbookmovie.com&language=en'
      }
    };
  }

  render() {
    return (
      <div className="container-fluid">
        <div className="navbar-fixed">
          <nav>
            <div className="nav-wrapper indigo lighten-4">
              <a href="/" className="brand-logo center">RF News Feed as of 6 DEC 2021</a>
            </div>
          </nav>
        </div>
        <div className="row">
          <div className="col s8">
            <News news={this.state.news1} />
            <News news={this.state.news2} />
            <div id="banner-ad"
              style= { {
                width: 300,
                height: 250
              }}> 
              <AdvertisingProvider config={config} />
              <AdvertisingSlot config={config} />
            </div> 
          </div>
          <div className="col s4">
            <SideFeed news={this.state.news3}/>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

第 2 步:唯一的广告依赖项位于下面的 config.js 中:

import React from 'react';

const config = {
    slots: [
      {
        id: "banner-ad",
        path: "/6355419/Travel/Europe/France/Paris",
        sizes: [[300, 250]]
          }
        ]
    };

export default config;
  

任何人都可以看一下或向我推荐有关React的GPT广告实施的资源吗?

reactjs ads
1个回答
0
投票

问题

我看到您尝试获取 npm 软件包,但不需要。在这里,我将用更新的代码解释如何像普通网页实现一样进行操作。

使用 ReactJS 和 Typescript 实施 Google 发布商代码广告

您好,我知道文档 GPT(Google 发布商标签)不太好并且缺少一些信息...

所以在这里我将描述如何在我的 ReactJS(使用 Typescript)应用程序中实现 GPT 广告。

首先,我通过添加 window.googletag 属性并配置它来初始化广告。

inits/gptAds.ts

export const initialiseGPTAds = () => {
  if (typeof window !== 'undefined') {
    // Ensure we can interact with the GPT command array.
    window.googletag = window.googletag || { cmd: [] };

    // Prepare GPT to display ads.
    googletag.cmd.push(() => {
      // Disable initial load, to precisely control when ads are requested.
      googletag.pubads().disableInitialLoad();

      // Enable SRA and services.
      googletag.pubads().enableSingleRequest();
      googletag.enableServices();
    });
    
     // Here I save my slots into my zustand or redux state so I can access them later and have better control.
    const { setAdSlots } = useAppStore.getState();
    setAdSlots({ count: 0, slots: {} }); 
  }
};

我将常量分开,这样我就可以在有限或不受限的广告库之间交换。

consts/gptAds.ts

export const gptAdsUrl = 'https://securepubads.g.doubleclick.net/tag/js/gpt.js';
export const gptLimitedAdsUrl = 'https://pagead2.googlesyndication.com/tag/js/gpt.js';

我创建了一个钩子,因此我在应用程序初始化(app.tsx)时调用它。该钩子将注入脚本库(受限或不受限),并将在加载时初始化广告。

挂钩/初始化GPT.tsx

import * as React from 'react';

import { gptAdsUrl, gptLimitedAdsUrl } from 'app/consts';
import { initialiseGPTAds } from 'app/inits';

const useInitializeGPT = (limitedAds: boolean = false) => {
  React.useEffect(() => {
    const scriptUrl = limitedAds ? gptLimitedAdsUrl : gptAdsUrl;

    const script = document.createElement('script');
    script.src = scriptUrl;
    script.async = true;

    document.head.appendChild(script);

    script.onload = () => initialiseGPTAds();

    // Cleanup function to remove the script when the component unmounts
    return () => {
      document.head.removeChild(script);
    };
  }, [limitedAds]);
};

export default useInitializeGPT;

然后我在我的 main.tsx 或 app.tsx 上这样调用:

 useInitializeGPT(false);

我创建了一些服务,以便我可以定义广告位、销毁定义的广告位、请求广告并获取最小广告位大小(用于横幅)。

这里我定义了广告位并保存到我的状态中以便更好地控制。每个广告位都需要尺寸(用于横幅)和 AdUnit。 您可以使用测试 AdUnit 例如“/6355419/Travel/Europe”来测试。

服务/gptAds/defineAdSlot.ts

import { useAppStore } from 'shared/store';
import { reportError } from 'shared/utils';

export const defineAdSlot = (adUnit: string, size: googletag.GeneralSize) => {
  const { adSlots, addAdSlot } = useAppStore.getState();

  try {
    const newSlotId = `slot-${adSlots.count}`;
    let newSlot: googletag.Slot | undefined;

    googletag.cmd.push(() => {
      const slot = googletag.defineSlot(adUnit, size, newSlotId);

      if (!slot) throw new Error('defineAdSlot: Not possible to add ad slot.');

      slot.addService(googletag.pubads());
      googletag.display(slot);
      addAdSlot(slot, newSlotId);
      newSlot = slot;
    });

    return { newSlot, newSlotId };
  } catch (error) {
    reportError(error, 'defineAdSlot');
    return { newSlot: undefined, newSlotId: undefined };
  }
};

在这里,我销毁了该插槽,以防来回导航并避免口是心非。

服务/gptAds/destroyAdSlot.ts

import { useAppStore } from 'shared/store';
import { reportError } from 'shared/utils';

export const destroyAdSlot = (slotId: string) => {
  const { removeAdSlot, adSlots } = useAppStore.getState();

  try {
    googletag.cmd.push(() => {
      if (adSlots.slots[slotId]) {
        googletag.destroySlots([adSlots.slots[slotId]]);
        removeAdSlot(slotId);
      }
    });
  } catch (error) {
    reportError(error, 'destroyAdSlot');
  }
};

这里的这个函数主要是一个推荐(来自官方 GPTAds 示例),所以我在渲染广告时在布局中使用(请检查下面)。

服务/gptAds/getMinimumSlotSize.ts

export const getMinimumSlotSize = (size: googletag.GeneralSize) => {
  const maxValue = Number.MAX_VALUE;

  let minW = Number.MAX_VALUE;
  let minH = Number.MAX_VALUE;

  if (Array.isArray(size)) {
    // Convert googletag.SingleSize to googletag.MultiSize for convenience.
    const sizes = size.length <= 2 && !Array.isArray(size[0]) ? [size] : size;

    for (const s of sizes) {
      if (Array.isArray(s) && s[0] !== 'fluid') {
        minW = Math.min(+s[0], minW);
        minH = Math.min(+s[1], minH);
      }
    }
  }

  return minW < maxValue && minH < maxValue
    ? // Static ad slot.
      { minWidth: `${minW}px`, minHeight: `${minH}px` }
    : // Fluid ad slot.
      { minWidth: '50%' };
};

在这里,我请求将广告位作为参数提供的广告。

服务/gptAds/requestAds.ts

import { reportError } from 'shared/utils';

export const requestAds = (adSlots: Record<string, googletag.Slot>) => {
  try {
    googletag.cmd.push(() => {
      const slots = Object.values(adSlots);
      googletag.pubads().refresh(slots);
    });

    return true;
  } catch (error) {
    reportError(error, 'requestAds');
    return false;
  }
};

这是我在组件中渲染的方式,以便它可以在任何地方显示。我使用 React.memo 来避免重新渲染广告位并导致问题。

组件/adSlotContainer.tsx

const AdSlotContainerComponent = ({ adUnit, size }: Props) => {
  const hasLoaded = React.useRef<boolean>(false);
  const [slotId, setSlotId] = React.useState<string>();

  React.useEffect(() => {
    if (hasLoaded.current) return;

    const { newSlot, newSlotId } = defineAdSlot(adUnit, size);

    if (!newSlot || !newSlotId) return () => {};

    const requested = requestAds({ [newSlotId]: newSlot });

    if (!requested) return () => {};

    hasLoaded.current = true;

    setSlotId(newSlotId);

    return () => {
      slotId && destroyAdSlot(slotId);
    };
  }, [adUnit, size]);

  return slotId ? (
    <div
      className={classes(styles.adSlot, styles.centered)}
      style={getMinimumSlotSize(size)}
      id={slotId}
      key={slotId}
    ></div>
  ) : null;
};

const propsAreEqual = (prev: Props, next: Props) => {
  return prev.adUnit === next.adUnit && prev.size === next.size;
};

export const AdSlotContainer = React.memo(AdSlotContainerComponent, propsAreEqual);

最后,这是我如何在任何组件中渲染它:

页面/测试/组件/horizontalContainer.tsx

import { AdSlotContainer } from 'app/components';

import styles from './styles.module.scss';

export const HorizontalContainer = () => {
  return (
    <div className={styles.container}>

      <div className={styles.bannerAd}>
        <AdSlotContainer adUnit="/6355419/Travel/Europe" size={sizes.bottomDesktop} />
      </div>

    </div>
  );
};

这里是要使用的横幅尺寸示例:

// Here are just examples of sizes
const sizes: Record<string, googletag.GeneralSize> = {
  bottomMobileBanner: [468, 60], // Full Banner
  bottomDesktopBanner: [728, 90], // Leaderboard
  rightDesktopRect: [300, 250], // Medium Rectangle
  rightDesktopTall: [160, 600], // Wide skyscraper
};

注意事项: 在我的项目中,我已经组织好了所有文件夹,所以我建议相同,并且还使用索引(导出*)文件来使绝对导入更好。我到处都有“reportError”功能,它会发送到我的 Crashlytics 或 Sentry 并记录它。

我还添加了库“@types/google-publisher-tag”作为开发依赖项,并将其包含在 tsconfig.json 中的类型中:

"types": [(...), "google-publisher-tag"]
,以便类型正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.