UNPKG

google-publisher-tag

Version:

Type-safe React wrapper for Google Publisher Tag (GPT).

83 lines (82 loc) 3.23 kB
"use client"; import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useContext, useEffect, useMemo, useRef, } from "react"; import { loadGPT } from "./loader"; const GPTContext = createContext(null); export function GPTProvider({ children, config, }) { const configuredRef = useRef(false); const cfg = useMemo(() => config ?? {}, [config]); useEffect(() => { loadGPT().then((googletag) => { if (configuredRef.current) return; configuredRef.current = true; googletag.cmd.push(() => { const pubads = googletag.pubads(); if (cfg.enableSingleRequest) pubads.enableSingleRequest(); if (cfg.lazyLoad) pubads.enableLazyLoad(cfg.lazyLoad === true ? {} : cfg.lazyLoad); if (cfg.forceSafeFrame) pubads.setForceSafeFrame(true); if (cfg.requestNonPersonalizedAds != null) pubads.setPrivacySettings({ nonPersonalizedAds: !!cfg.requestNonPersonalizedAds, }); if (cfg.targeting) { Object.entries(cfg.targeting).forEach(([k, v]) => pubads.setTargeting(k, v)); } googletag.enableServices(); (cfg.slots ?? []).forEach((slotCfg) => { defineSlotInternal(googletag, slotCfg); }); }); }); }, [cfg]); const defineSlot = (slotCfg) => loadGPT().then((googletag) => new Promise((resolve) => { googletag.cmd.push(() => { const handle = defineSlotInternal(googletag, slotCfg); resolve(handle); }); })); const setTargeting = (t) => loadGPT().then((googletag) => new Promise((resolve) => { googletag.cmd.push(() => { const pubads = googletag.pubads(); Object.entries(t).forEach(([k, v]) => pubads.setTargeting(k, v)); resolve(); }); })); const value = useMemo(() => ({ configured: configuredRef.current, config: cfg, defineSlot, setTargeting, }), [cfg]); return _jsx(GPTContext.Provider, { value: value, children: children }); } function defineSlotInternal(googletag, cfg) { const pubads = googletag.pubads(); const slot = cfg.outOfPage ? googletag.defineOutOfPageSlot(cfg.adUnitPath, cfg.id) : googletag.defineSlot(cfg.adUnitPath, cfg.sizes, cfg.id); if (!slot) return { slot: null, destroy: () => { } }; if (cfg.sizeMapping && slot.defineSizeMapping) { const sm = googletag.sizeMapping(); cfg.sizeMapping.forEach(([vp, sizes]) => sm.addSize(vp, sizes)); slot.defineSizeMapping(sm.build()); } slot.addService(pubads); if (cfg.targeting) Object.entries(cfg.targeting).forEach(([k, v]) => slot.setTargeting(k, v)); return { slot, destroy: () => googletag.destroySlots([slot]), }; } export function useGPT() { const ctx = useContext(GPTContext); if (!ctx) throw new Error("useGPT deve ser usado dentro de <GPTProvider />"); return ctx; }